java-XML
XML不再多說,XML 約束也不用說了,這里講講java如何對XML操作。
java中使用XML,目前常用的就是Jaxp(sun)和dom4j了,這里先講講java自帶的Jaxp包
Jaxp的xml解析器有兩種,一種是DOM解析器,一種是SAX解析器,兩種各自應用在不同的場景上。
在DOM解析時,會把xml中各個節點視為對象,然后根據父子關系相互嵌套。優點時容易操縱,缺點也很明顯,必須全部通讀xml并加載進內存。
DOM解析的流程:
1,DocumentBuilderFactory是抽象類,newInstance()方法會根據本地平臺安裝的xml解析器自動創建相應的工廠實力
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
2,DocumentBuilder的newDocumentBuilder()方法會得到本地xml解析器相應的DocumentBuilder實力
DocumentBuilder documentB = dbf.newDocumentBuilder();
3,解析xml,根據DocumentBuilder的parse方法。
Document document = documentB.parse(new File(path));
//看文檔可以知道,parse可以從解析File、InputSource(經過包裝的InputStream)、InputStream和URI字符串
4,Document代表了整個XML文檔,首先獲取根節點,Element就是標簽,它們都屬于Node,也就是說,都實現了Node接口
Element root=document.getDocumentElement();
5,下面就是增刪改查了
增加結點
//增加一個結點,注意,增加節點是對document操作,Document實現了這個方法
Element newStudent=document.createElement("student");
//增加一個屬性,屬性也算是結點,一切都是Node
Attr cid=document.createAttribute("idcard");
//給屬性設置值
cid.setValue("1121");
//將屬性添加進這個標簽
newStudent.setAttributeNode(cid);
//最后,將這個結點添加進根節點,注意,是對根節點添加,不是Document
root.appendChild(newStudent);
提取某節點信息(查)
//首先根據第3步,已經獲得根結點,也就是Element root
//獲取所有標簽名為sutdent的節點集合
NodeList students=root.getElementsByTagName("student");
//至于獲取標簽屬性以及text內容,自行看手冊
//要注意的是,換行和制表符'\n\t'這些,也會被當做text內容解析
//至于xml的編碼問題,都是自動的,不用手動設置了。
更改結點內容(很多都是Node接口的方法,自行查看手冊即可)
//設置標簽內容 Node.setTextContent(String text) //設置屬性內容 Attr.setValue(String value)
刪除結點
Node.removeChild(Node node)
6,操作完xml,保存結果
//1、獲得Transformer工廠 TransformerFactory tff=TransformerFactory.newInstance(); //2、對于DOM對象,使用樹來表示,肯定是個多叉樹了,,, //這個類,就是將樹,變為結果樹 Transformer tf = tff.newTransformer(); //3、把document(DOM)轉換為xml source Source sc=new DOMSource(document); //4、創建一個DOM目標,這里是個流 Result rs=new StreamResult(new File(path_URI)); //5、將 XML Source 轉換為 Result,這樣就寫入數據流了 tf.transform(sc, rs);
DOM解析就到這里,如果以網絡流讀取一個大的xml文件的話,這樣肯定是不行的,不可能一直等到它全部讀完載入內存再操作吧。。。。。光讀取的話,就用SAX了。
事件處理器由程序員編寫,程序員通過事件處理器中方法的參數,就可以很輕松地得到sax解析器解析到的數據,從而可以決定如何對數據進行處理

我們常用的就是ContentHandler了。
下面是sax示例
//定義工廠api,用以配置和獲取sax解析器
SAXParserFactory spf = SAXParserFactory.newInstance();
//得到解析器對象
SAXParser sp = spf.newSAXParser();
//得到一個xmlreader讀取器
XMLReader xmlReader = sp.getXMLReader();
//注冊一個內容事件處理器 ContentHandler,一般情況下,使用ContentHandler接口的已知
//子類DefaultHandler就行了
xmlReader.setContentHandler(new DefaultHandler(){
//為了方便,以內部類重寫需要使用到的方法
//開始讀取標簽
public void startElement(String uri, //命名空間
String localName, //標簽名
String qName, //限定名稱
Attributes attributes //屬性
){
///////////////////////////
//獲取標簽的個數
attr.getLength();
//其它的看手冊
}
//開始讀取文檔
public void startDocument(){
}
//讀取到標簽尾
public void endElement( String namespaceURI,
String localName,
String qName ) {
}
//讀取標簽體,注意的是,sax是分段讀取的,每次最大讀取是2kb
public void characters(char[] ch,
int start,
int length
){
//讀取大數據的時候注意sax是分段讀取的,每次最大讀取是2kb
}
});
//開始讀取xml數據
xmlReader.parse("book.xml");
到這里,我們發現SAX雖然比DOM效率高,但是它是順序讀取的,無法回頭,且只能從頭到尾。
現在就可以使用Dom4j了,它是第三方包
//1.讀取XML文件,獲得document對象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
//2.解析XML形式的文本,得到document對象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);
//3.主動創建document對象.
Document document = DocumentHelper.createDocument(); //創建根節點
Element root = document.addElement("members");
dom4j 中結點對象的操作:
//1.獲取文檔的根節點.
Element root = document.getRootElement();
//2.取得某個節點的子節點.
Element element=node.element(“書名");
//3.取得節點的文字
String text=node.getText();
//4.取得某節點下所有名為“member”的子節點,并進行遍歷.
List nodes = rootElm.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something
}
//5.對某節點下的所有子節點進行遍歷.
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something
}
//6.在某節點下添加子節點.
Element ageElm = newMemberElm.addElement("age");
//7.設置節點文字.
element.setText("29");
//8.刪除某節點.
//childElm是待刪除的節點,parentElm是其父節點
parentElm.remove(childElm);
//9.添加一個CDATA節點.
Element contentElm = infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());
對節點對象屬性的操作:
//1.取得某節點下的某屬性
Element root=document.getRootElement();
//屬性名name
Attribute attribute=root.attribute("size");
//2.取得屬性的文字
String text=attribute.getText();
//3.刪除某屬性
Attribute attribute=root.attribute("size");
root.remove(attribute);
//4.遍歷某節點的所有屬性
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text);
}
//5.設置某節點的屬性和文字.
newMemberElm.addAttribute("name", "sitinspring");
//6.設置屬性的文字
Attribute attribute=root.attribute("name");
attribute.setText("sitinspring");
在指定位置中插入元素:
//Element元素可以通過DocumentHelper對象得到。示例代碼:
Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");
List list = root.element("書").elements();
list.add(1, aaa);
寫入XML文檔
//1.文檔中全為英文,不設置編碼,直接寫入的形式.
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
//2.文檔中含有中文,設置編碼格式寫入的形式.OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML編碼
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
writer.write(document);
writer.close();
XML與字符串的轉換
//1.將字符串轉化為XML
String text = "<members> <member>sitinspring</member></members>";
Document document = DocumentHelper.parseText(text);
//2.將文檔或節點的XML轉化為字符串.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
Element root=document.getRootElement();
String docXmlText=document.asXML();
String rootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();
在Dom4j中使用xpath查詢路徑
xpath路徑表達式就像正則表達式一樣,可以免去自己寫遍歷對比代碼了。
//dom4j的包中的document..........
List<Node> list = document.selectNodes("http://xpath");
上面的所有代碼基本上算是模板代碼了,用的時候多看手冊,拷貝粘貼就ok了
浙公網安備 33010602011771號