XML解析的三种方式(dom,sax,dom4j)
生活随笔
收集整理的這篇文章主要介紹了
XML解析的三种方式(dom,sax,dom4j)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.Dom解析:
要解析的xml文件內容:
<?xml version="1.0" encoding="utf-8" standalone="no"?><class><stu id="1"><name>小灰灰</name><age>23</age><insto>好學生</insto></stu><stu id="2" sex="女"><name>小紅</name><age>20</age><insto>學生</insto></stu><stu><name>小暉</name><age>20</age><insto>三好學生</insto></stu> </class>java解析代碼:
package com.huihui.dom;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; 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.Node; import org.w3c.dom.NodeList;//使用DOM技術對xml文件進行crud操作 public class DomXml1 {public static void main(String[] args) throws Exception {// 創建一個DocumentBuilderFactoryDocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();// 通過DocumentBuilderFactory得到一個DocumentBuilder對象DocumentBuilder dBuilder = dbf.newDocumentBuilder();// 指定解析哪個xml文件Document document = dBuilder.parse("src/myclass.xml");// System.out.println(document);// 遍歷該xml文件//list(document);//read(document);//add(document);//delete(document);//update(document);System.out.println("OK");}// 更新xml文件private static void updateXML(Document doc)throws TransformerFactoryConfigurationError, TransformerConfigurationException, TransformerException {// 得到TransformerFactory對象TransformerFactory tff = TransformerFactory.newInstance();// 通過TransformerFactory得到一個轉化器Transformer tf = tff.newTransformer();// 將doc的整個在內存中的節點樹寫出到外部的文件中tf.transform(new DOMSource(doc), new StreamResult("src/myclass.xml"));}// 遍歷xml節點(也就是遍歷樹)public static void list(Node node) {// 如果該節點類型是node節點(而不是文本節點)if (node.getNodeType() == node.ELEMENT_NODE) {System.out.println("名字:" + node.getNodeName());}// 取出node的子節點NodeList nodeList = node.getChildNodes();for (int i = 0; i < nodeList.getLength(); i++) {// 取出節點Node n = nodeList.item(i);// 運用遞歸,再去顯示(節點的子節點)list(n);}}// 具體查詢某個學生的信息(顯示第一個學生的所有信息)public static void read(Document doc) {NodeList nl = doc.getElementsByTagName("stu");// 在document的級別層級上往下獲取元素// 取出第一個學生Element stu = (Element) nl.item(0);Element name = (Element) stu.getElementsByTagName("name").item(0);System.out.println("學生的姓名是:" + name.getTextContent());// 取出name的值System.out.println("學生的性別是:" + stu.getAttribute("sex"));// 取出stu的屬性值}// 添加一個stu到xml文件中去public static void add(Document doc) throws Exception {// 創建一個新的學生節點Element newstu = doc.createElement("stu");Element newstu_name = doc.createElement("name");newstu_name.setTextContent("小暉");Element newstu_age = doc.createElement("age");newstu_age.setTextContent("20");Element newstu_insto = doc.createElement("insto");newstu_insto.setTextContent("三好學生");newstu.appendChild(newstu_name);newstu.appendChild(newstu_age);newstu.appendChild(newstu_insto);// 把新的學生節點添加到根元素下(雖然這也添加進取了,但是查看xml文件,會發現xml文件沒有任何的變化,原因是現在的整個document是解析xml文件出來的、在內存中的。所以你只是改變的是內存中的內容,并沒有對文件本身產生影響)doc.getDocumentElement().appendChild(newstu);// 更新xml文件updateXML(doc);}// 刪除一個節點或者一個節點的屬性(刪除第一個學生或者第一個學生的性別屬性)public static void delete(Document doc) throws Exception {// 刪除第一個學生// Node node = doc.getElementsByTagName("stu").item(0);// node.getParentNode().removeChild(node);//獲取到該節點的父節點后,從父節點中刪除這個元素(也只是在內存的dom樹中進行了刪除,并不會影響xml文件的內容)// 刪除第一個學生的sex屬性Element node = (Element) doc.getElementsByTagName("stu").item(0);node.removeAttribute("sex");// 更新xml文件updateXML(doc);}// 更新節點的內容(把第一個學生的名字改成小灰灰)public static void update(Document doc) throws Exception {Element node = (Element) doc.getElementsByTagName("stu").item(0);Element node_name = (Element) node.getElementsByTagName("name").item(0);node_name.setTextContent("小灰灰");// 更新xml文件updateXML(doc);}}2.SAX解析:
要解析的xml文件內容:
<?xml version="1.0" encoding="UTF-8"?> <class><stu id="1" sex="男"><name>小灰灰</name><age>23</age><insto>好學生</insto></stu><stu id="2" sex="女"><name>小紅</name><age>20</age><insto>學生</insto></stu><stu><name>小暉</name><age>20</age><insto>三好學生</insto></stu> </class>java解析代碼:
package com.huihui.sax;import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;public class SaxXml1 {// 使用sax技術解析XML文件public static void main(String[] args) throws Exception {// 1.使用SAXParserFactory創建SAX解析工廠SAXParserFactory spf = SAXParserFactory.newInstance();// 2.通過SAX解析工廠得到解析器對象SAXParser saxParser = spf.newSAXParser();// 3.解析器將解析對象和事件處理對象關聯saxParser.parse("src/myclass2.xml", new MyDefaultHandler1());}}// 定義第二個事件處理類(如何只顯示stu的name和age) class MyDefaultHandler1 extends DefaultHandler {private boolean isName = false;private boolean isAge = false;@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {String con = new String(ch, start, length);if(!"".equals(con.trim())&&(isName||isAge)){System.out.println(con);}isName = false;isAge = false;}@Overridepublic void endDocument() throws SAXException {}@Overridepublic void endElement(String uri, String localName, String qName) throws SAXException {}@Overridepublic void startDocument() throws SAXException {}@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {if("name".equals(qName)){isName = true;}else if("age".equals(qName)){isAge = true;}}}// 定義事件處理類(顯示stu的所有信息) class MyDefaultHandler extends DefaultHandler {@Override// 發現文檔開始public void startDocument() throws SAXException {System.out.println("startDocument()方法");}@Override// 發現xml文件中的一個元素public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {System.out.println("屬性名稱:" + qName);}@Override// 發現xml文件中的文本public void characters(char[] ch, int start, int length) throws SAXException {String con = new String(ch, start, length);// 顯示文本內容if (!con.trim().equals("")) {System.out.println(con);}}@Override// 發現xml文件中的一個元素結束public void endElement(String uri, String localName, String qName) throws SAXException {super.endElement(uri, localName, qName);}@Override// 發現文檔結束public void endDocument() throws SAXException {System.out.println("endDocument()方法");}}3.DOM4J解析:
要解析的xml文件內容:
<?xml version="1.0" encoding="utf-8"?><class> <student> <name myname="xiaohong">小紅</name> <sex>girl</sex> <age>15</age> </student> <student> <name myname="xiaoming">小明</name> <sex>boy</sex> <age>13</age> </student> </class>java解析代碼:
package com.huihui.dom4j;import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Iterator; import java.util.List;import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter;//使用Dom4j對xml文件進行crud操作 public class MyDom4jTest1 {public static void main(String[] args) throws Exception {// 得到解析器SAXReader saxReader = new SAXReader();// 指定解析哪個xml文件Document document = saxReader.read(new File("src/class.xml"));// 獲取xml文件的根元素Element root = document.getRootElement();// list(root);// read(document);// add(document);//delete(document);//update(document);addByIndex(document);}// 遍歷xml文件public static void list(Element element) {System.out.println(element.getName());// 打印元素名稱System.out.println(element.getTextTrim());// 打印元素中的文本內容Iterator iterator = element.elementIterator();while (iterator.hasNext()) {Element e = (Element) iterator.next();// 遞歸list(e);}}// 指定讀取某個元素(eg:讀取第一個學生的信息)public static void read(Document document) {Element root = document.getRootElement();// 獲取根元素// root.element("student"):表示取出root元素下的一個student元素// root.elements("student"):表示取出根元素下的所有student元素// root.elements("student").get(0):表示取出根元素下的第一個student元素Element e = (Element) root.elements("student").get(1);// 取出元素下的內容值System.out.println(e.element("name").getText());// 取出元素中的屬性值System.out.println(e.element("name").attributeValue("myname"));/*** 測試能否跨層去取出元素 測試結果:IndexOutOfBoundsException 結果:不能跨層取出元素,除非使用xPath技術*/// Element e1 = (Element) root.elements("name").get(0);// 從正常的數據中取出后}// 添加元素(eg:添加一個student元素到xml文件中去)public static void add(Document document) throws Exception {// 創建一個student元素對象Element newStu = DocumentHelper.createElement("student");Element newStu_name = DocumentHelper.createElement("name");newStu_name.addAttribute("myname", "xiaofang");// 給元素添加屬性newStu_name.setText("小芳");// 給元素添加內容Element newStu_sex = DocumentHelper.createElement("sex");Element newStu_age = DocumentHelper.createElement("age");// 把三個子元素掛載到newStu下newStu.add(newStu_name);newStu.add(newStu_sex);newStu.add(newStu_age);// 再把newStu元素加到根元素下document.getRootElement().add(newStu);// 把xml文件更新一下updateXML(document);}// 刪除元素(eg:刪除第一個student元素)public static void delete(Document document) throws Exception {// 找到第一個student元素Element e = (Element) document.getRootElement().elements("student").get(0);// 刪除找到的student元素// e.getParent().remove(e);// 刪除某元素的某個屬性(刪除name元素的myname屬性)Element e_name = (Element) e.elements("name").get(0);e_name.remove(e_name.attribute("myname"));updateXML(document);}// 更新元素(eg:把所有student元素的age都加3)public static void update(Document document) throws Exception {// 得到所有student的ageList<Element> elements = document.getRootElement().elements("student");for (Element e1 : elements) {// 從student中取出age元素Element age = e1.element("age");age.setText(Integer.parseInt(age.getText()) + 3 + "");//修改age元素的內容文本//從student中取出name元素Element name = e1.element("name");name.addAttribute("myname", "haha");//修改name元素的myname屬性}updateXML(document);}//添加一個元素到指定的位置(添加一個student,在每個name為小紅的student元素之后,在小明之前)public static void addByIndex(Document document) throws Exception{//創建一個student元素Element newStu = DocumentHelper.createElement("student");Element newStu_name = DocumentHelper.createElement("name");newStu_name.setText("小華");Element newStu_sex = DocumentHelper.createElement("sex");newStu_sex.setText("男");Element newStu_age = DocumentHelper.createElement("age");newStu_age.setText("30");//將name,sex,age元素掛載到student元素下面newStu.add(newStu_name);newStu.add(newStu_sex);newStu.add(newStu_age);//得到所有student元素的List(循環遍歷的目的是如果有多個name是小紅的student元素,那么就要在每個name為小紅的student元素之后添加新的student元素)List<Element> elements = document.getRootElement().elements("student");for (int i = 0; i < elements.size(); i++) {//取出各個student的name元素Element name = elements.get(i).element("name");if("小紅".equals(name.getText())){elements.add(i+1,newStu);//在位置1(也就是xml文檔中的第二個位置)添加元素}}//更新xml文檔updateXML(document);}//更新xml文檔private static void updateXML(Document document)throws UnsupportedEncodingException, FileNotFoundException, IOException {// 如果元素名稱為中文,直接輸出就會出現中文亂碼問題,使用OutputFormat解決中文亂碼的問題OutputFormat format = OutputFormat.createPrettyPrint();format.setEncoding("utf-8");XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(new File("src/class.xml")), format);xmlWriter.write(document);xmlWriter.close();}}DOM4J補充說明:
XPath:
為什么使用XPath?
1.為了我們更方便的訪問某個節點,我們可以使用xpath技術,當使用xpath之后,就可以非常方便的讀取到指定的節點了(可以跨層取出元素).
2.xpath往往是結合DOM4J搭配一起使用
3.注意:要引入jaxen-1.1-beta-6.jar包
Dom4j結合xpath一起使用的案例:
要解析的xml文件:
java解析代碼:
package com.huihui.dom4j;import java.io.File; import java.util.List;import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;//dom4j配合xpath使用的案例 public class Dom4jAndXpath {public static void main(String[] args) {try {//1.得到SAXReader解析器SAXReader saxReader = new SAXReader();//2.指定要解析的xml文件Document document = saxReader.read(new File("src/class.xml"));//3.可以隨心所欲的讀取xml文件了//基本的XPath語法類似于在一個文件系統中定位文件,如果路徑以斜線 / 開始, 那么該路徑就表示到一個元素的絕對路徑 // List<Element> list = document.selectNodes("/class/student/sex");//取出class元素下邊的student元素下的所有的sex元素 // for (int i = 0; i < list.size(); i++) { // String text = list.get(i).getText(); // System.out.println("所有的sex元素的內容:"+text); // }//如果路徑以雙斜線 // 開頭, 則表示選擇文檔中所有滿足雙斜線//之后規則的元素(無論層級關系) // List<Element> list = document.selectNodes("//student"); // System.out.println(list.size());//星號 * 表示選擇所有由星號之前的路徑所定位的元素List<Element> list = document.selectNodes("/class/student/*");System.out.println(list.size());} catch (Exception e) {e.printStackTrace();}}}xpath的一些相關內容的說明:
1.基本的XPath語法類似于在一個文件系統中定位文件,如果路徑以斜線 / 開始, 那么該路徑就表示到一個元素的絕對路徑
2.如果路徑以雙斜線 // 開頭, 則表示選擇文檔中所有滿足雙斜線//之后規則的元素(無論層級關系)
3.星號 * 表示選擇所有由星號之前的路徑所定位的元素
4.方塊號里的表達式可以進一步的指定元素, 其中數字表示元素在選擇集里的位置, 而last()函數則表示選擇集中的最后一個元素.
總結
以上是生活随笔為你收集整理的XML解析的三种方式(dom,sax,dom4j)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自定义myeclipse中的servle
- 下一篇: HTML5中本地数据库(SQLLite)