xml解析技術分爲兩種:民間的 和 官方的。
民間的就是鼎鼎有名的SAX(Simple API for XML),是 XML 社區提供的標準,幾乎所有的 XML 解析器都支持它。
官方的自然是權威機構W3C組織出臺的DOM(Document ObjectModel)了,今天先初探下官方的技術。
根據W3C DOM規範,DOM是HTML與XML的應用編程接口(API),
DOM將整個頁面映射爲一個由層次節點組成的文件。
利用DOM解析xml就是找到節點,獲取節點屬性等等。有點類似於查找數據庫的某條記錄,從而獲取某個記錄的字段值。
而xml也經常用於存儲數據,於是乎,咱們可以按照操作數據庫對象的CRUD方式來操作xml文檔:
<暫且利用j2se的JAXP(JavaAPIforXMLProcessing)對xml解析>
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class OperateXML {
private Document document;
private String xmlPath;
/**
* 獲取xml文檔,類似於 數據庫建立連接
* @param xmlPath xml文件的路徑
* */
public void getXML(String xmlPath){
this.xmlPath = xmlPath;
//1、創建工廠
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//2、得到DOM解析器
try {
DocumentBuilder builder = factory.newDocumentBuilder();
//3、解析xml文檔,得到代表文檔的document
document = builder.parse(xmlPath);
System.out.println("xml文檔已經獲取");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
/**
* 獲取元素節點集合,類似於 數據庫中具體某張表
* @param tagName:節點名,如:<book id="1" name="java"></book>中tagName="book";
* @return NodeList:節點集合,此處返回節點名稱同爲tagName的集合
* */
public NodeList getNodelist(String tagName){
return document.getElementsByTagName(tagName);
}
/**
* 獲取元素節點,類似於 數據庫中具體某張表的某條記錄
* @param attrName:表示屬性名,類似於數據庫字段名
* @param attrValue:表示屬性值,類似於數據庫字段值
* @param nodelist:節點集合
* @return Element:表示 XML 文檔中的一個元素節點
* */
public Element getElt(String attrName, String attrValue,NodeList nodelist){
Element elt = null;
for(int i=0; i<nodelist.getLength(); i++)
{
elt = (Element)nodelist.item(i);//Element實現了node接口,可以強轉
if(elt.getAttribute(attrName).equals(attrValue))
break;
else
continue;
}
return elt;
}
/**
* 獲取節點元素的屬性,類似於查找表中某條記錄的字段值
* @param elt:元素節點
* @param attrName:所要查找的屬性名
* @return String屬性值
* */
public String getAttribute(Element elt,String attrName){
return elt.getAttribute(attrName);
}
/**
* 修改節點屬性值,類似於更新數據庫字段值
* @param attrName:表示屬性名,類似於數據庫字段名
* @param attrValue:表示屬性值,類似於數據庫字段值
* @param elt:待修改屬性的節點
* */
public void modifyElt(String attrName, String attrValue,Element elt){
elt.setAttribute(attrName, attrValue);
//更新了內存中節點,需將內存中信息寫回xml文檔
toXmlFile();
}
/**
* 從xml中移除節點,類似於刪除某條數據表記錄
* @param elt:待刪除的節點
* @param superElt:父節點
* */
public void removeElt(Element elt,Element superElt){
superElt.removeChild(elt);
toXmlFile();
}
/**
* 新增一個節點,類似於數據表中新增一條記錄
* @param tagName:表示節點名,類似於數據表
* @param attrNameArr:節點的屬性名數組
* @param attrValueArr:節點的屬性值數組,須跟attrNameArr的數組一一對應
* @param superElt:表示要往哪個節點中添加子節點,可以理解爲往數據庫添加表
* */
public void addElt(String tagName, String[] attrNameArr, String[] attrValueArr, Element superElt){
//創建一個節點
Element elt = document.createElement(tagName);
//給節點賦予各種屬性
for(int i=0; i<attrNameArr.length; i++)
elt.setAttribute(attrNameArr[i], attrValueArr[i]);//屬性的初始值設置爲空
superElt.appendChild(elt);
//更新了內存中節點,需將內存中信息寫回xml文檔
toXmlFile();
}
/***
* 將更新的內存寫回到xml文檔
*/
private void toXmlFile(){
try {
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf;
tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream(xmlPath)));
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
}