1 XML檔案解析的4種方法
通常解析XML檔案有四種經典的方法。基本的解析方式有兩種,一種叫SAX,一種叫DOM。 SAX是基於事件流的解析,DOM是基於XML文檔樹結構的解析。在此基礎上,為了減少DOM、SAX的編碼量,出現了JDOM,其優點是,20-80原則(帕累託法則),極大減少了代碼量。通常情況下JDOM使用時滿足要實現的功能簡單,如解析、創建等要求。但在底層,JDOM還是使用SAX(最常用)、DOM、Xanan文件。另外一種是DOM4J,是一個非常非常優秀的Java XML API,具有效能優異、功能強大和極端易用的特點,同時它也是一個開放原始碼的軟體。如今你可以看到越來越多的Java 軟體都在使用DOM4J 來讀寫XML,特別值得一提的是連Sun 的JAXM 也在用DOM4J。具體四種方法的使用,百度一下,會有許多詳細的介紹。
2 XPath簡單介紹
XPath是一門在XML文件中尋找資訊的語言。 XPath用於在XML 文件中透過元素和屬性進行導航,並對元素和屬性進行遍歷。 XPath 是W3C XSLT 標準的主要元素,而XQuery 和XPointer 同時被建構於XPath 表達之上。因此,對XPath 的理解是許多高階XML 應用的基礎。 XPath非常類似對資料庫操作的SQL語言,或者說JQuery,它可以方便開發者抓起文件中需要的東西。其中DOM4J也支援XPath的使用。
3 DOM4J使用XPath
DOM4J使用XPath解析XML文件是,首先需要在專案中引用兩個JAR套件:
dom4j-1.6.1.jar:DOM4J軟體包,下載網址http://sourceforge.net/projects/dom4j/;
jaxen-xx.xx.jar:通常不加入此包,會引發異常(java.lang.NoClassDefFoundError: org/jaxen/JaxenException),下載網址http://www.jaxen.org/releases.html。
3.1 命名空間(namespace)的干擾
在處理由excel檔案或其他格式檔案轉換的xml檔案時,通常會遇到透過XPath解析無法獲得結果的情況。這種情況通常是由於命名空間的存在所導致的。以下述內容的XML檔案為例,透過XPath=" // Workbook/ Worksheet / Table / Row[1]/ Cell[1]/Data[1] "進行簡單的檢索,通常是沒有結果出現的。這就是由於命名空間namespace(xmlns="urn:schemas-microsoft-com:office:spreadsheet")所導致的。
複製代碼代碼如下:
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel " xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="81" ss:ExpandedRowCount="687" x:FullColumns="1" x:FullRows="1" ss:DefaultColumnWidth="52.5" ss:DefaultRowHeight="15.5625">
<Row ss:AutoFitHeight="0">
<Cell>
<Data ss:Type="String">敲程式碼的耗子</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0">
<Cell>
<Data ss:Type="String">Sunny</Data>
</Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
3.2 XPath對帶有命名空間的xml檔解析
第一種方法(read1()函數):使用XPath語法中自帶的local-name() 和namespace-uri() 指定你要使用的節點名稱和命名空間。 XPath表達式書寫較為麻煩。
第二種方法(read2()函數):設定XPath的命名空間,利用setNamespaceURIs()函數。
第三種方法(read3()函數):設定DocumentFactory()的命名空間,使用的函數是setXPathNamespaceURIs()。二和三兩種方法的XPath表達式書寫相對簡單。
第四種方法(read4()函數):方法和第三種一樣,但是XPath表達式不同(程式具體體現),主要是為了檢驗XPath表達式的不同,主要指完整程度,是否會對檢索效率產生影響。
(以上四種方法皆透過DOM4J結合XPath對XML檔案進行解析)
第五種方法(read5()函數):使用DOM結合XPath對XML檔案進行解析,主要是為了檢驗效能差異。
沒有什麼比程式碼更能說明問題的了!果斷上程式碼!
複製代碼代碼如下:
packageXPath;
importjava.io.IOException;
importjava.io.InputStream;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;
importjavax.xml.parsers.DocumentBuilder;
importjavax.xml.parsers.DocumentBuilderFactory;
importjavax.xml.parsers.ParserConfigurationException;
importjavax.xml.xpath.XPathConstants;
importjavax.xml.xpath.XPathExpression;
importjavax.xml.xpath.XPathExpressionException;
importjavax.xml.xpath.XPathFactory;
importorg.dom4j.Document;
importorg.dom4j.DocumentException;
importorg.dom4j.Element;
importorg.dom4j.XPath;
importorg.dom4j.io.SAXReader;
importorg.w3c.dom.NodeList;
importorg.xml.sax.SAXException;
/**
*DOM4JDOMXMLXPath
*/
publicclassTestDom4jXpath{
publicstaticvoidmain(String[]args){
read1();
read2();
read3();
read4();//read3()方法一樣,但是XPath表達式不同
read5();
}
publicstaticvoidread1(){
/*
*uselocal-name()andnamespace-uri()inXPath
*/
try{
longstartTime=System.currentTimeMillis();
SAXReaderreader=newSAXReader();
InputStreamin=TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath//XXX.xml");
Documentdoc=reader.read(in);
/*Stringxpath="//*[local-name()='Workbook'andnamespace-uri()='urn:schemas-microsoft-com:office:spreadsheet']"
+"/*[local-name()='Worksheet']"
+"/*[local-name()='Table']"
+"/*[local-name()='Row'][4]"
+"/*[local-name()='Cell'][3]"
+"/*[local-name()='Data'][1]";*/
Stringxpath="//*[local-name()='Row'][4]/*[local-name()='Cell'][3]/*[local-name()='Data'][ 1]";
System.err.println("=====uselocal-name()andnamespace-uri()inXPath====");
System.err.println("XPath:"+xpath);
@SuppressWarnings("unchecked")
List<Element>list=doc.selectNodes(xpath);
for(Objecto:list){
Elemente=(Element)o;
Stringshow=e.getStringValue();
System.out.println("show="+show);
longendTime=System.currentTimeMillis();
System.out.println("程式運行時間:"+(endTime-startTime)+"ms");
}
}catch(DocumentExceptione){
e.printStackTrace();
}
}
publicstaticvoidread2(){
/*
*setxpathnamespace(setNamespaceURIs)
*/
try{
longstartTime=System.currentTimeMillis();
Mapmap=newHashMap();
map.put("Workbook","urn:schemas-microsoft-com:office:spreadsheet");
SAXReaderreader=newSAXReader();
InputStreamin=TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath//XXX.xml");
Documentdoc=reader.read(in);
Stringxpath="//Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]";
System.err.println("=====usesetNamespaceURIs()tosetxpathnamespace====");
System.err.println("XPath:"+xpath);
XPathx=doc.createXPath(xpath);
x.setNamespaceURIs(map);
@SuppressWarnings("unchecked")
List<Element>list=x.selectNodes(doc);
for(Objecto:list){
Elemente=(Element)o;
Stringshow=e.getStringValue();
System.out.println("show="+show);
longendTime=System.currentTimeMillis();
System.out.println("程式運行時間:"+(endTime-startTime)+"ms");
}
}catch(DocumentExceptione){
e.printStackTrace();
}
}
publicstaticvoidread3(){
/*
*setDocumentFactory()namespace(setXPathNamespaceURIs)
*/
try{
longstartTime=System.currentTimeMillis();
Mapmap=newHashMap();
map.put("Workbook","urn:schemas-microsoft-com:office:spreadsheet");
SAXReaderreader=newSAXReader();
InputStreamin=TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath//XXX.xml");
reader.getDocumentFactory().setXPathNamespaceURIs(map);
Documentdoc=reader.read(in);
Stringxpath="//Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]";
System.err.println("=====usesetXPathNamespaceURIs()tosetDocumentFactory()namespace====");
System.err.println("XPath:"+xpath);
@SuppressWarnings("unchecked")
List<Element>list=doc.selectNodes(xpath);
for(Objecto:list){
Elemente=(Element)o;
Stringshow=e.getStringValue();
System.out.println("show="+show);
longendTime=System.currentTimeMillis();
System.out.println("程式運行時間:"+(endTime-startTime)+"ms");
}
}catch(DocumentExceptione){
e.printStackTrace();
}
}
publicstaticvoidread4(){
/*
*同read3()方法一樣,但是XPath表達式不同
*/
try{
longstartTime=System.currentTimeMillis();
Mapmap=newHashMap();
map.put("Workbook","urn:schemas-microsoft-com:office:spreadsheet");
SAXReaderreader=newSAXReader();
InputStreamin=TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath//XXX.xml");
reader.getDocumentFactory().setXPathNamespaceURIs(map);
Documentdoc=reader.read(in);
Stringxpath="//Workbook:Worksheet/Workbook:Table/Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]";
System.err.println("=====usesetXPathNamespaceURIs()tosetDocumentFactory()namespace====");
System.err.println("XPath:"+xpath);
@SuppressWarnings("unchecked")
List<Element>list=doc.selectNodes(xpath);
for(Objecto:list){
Elemente=(Element)o;
Stringshow=e.getStringValue();
System.out.println("show="+show);
longendTime=System.currentTimeMillis();
System.out.println("程式運行時間:"+(endTime-startTime)+"ms");
}
}catch(DocumentExceptione){
e.printStackTrace();
}
}
publicstaticvoidread5(){
/*
*DOMandXPath
*/
try{
longstartTime=System.currentTimeMillis();
DocumentBuilderFactorydbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);
DocumentBuilderbuilder=dbf.newDocumentBuilder();
InputStreamin=TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath//XXX.xml");
org.w3c.dom.Documentdoc=builder.parse(in);
XPathFactoryfactory=XPathFactory.newInstance();
javax.xml.xpath.XPathx=factory.newXPath();
//選取所有class元素的name屬性
Stringxpath="//Workbook/Worksheet/Table/Row[4]/Cell[3]/Data[1]";
System.err.println("=====DomXPath====");
System.err.println("XPath:"+xpath);
XPathExpressionexpr=x.compile(xpath);
NodeListnodes=(NodeList)expr.evaluate(doc,XPathConstants.NODE);
for(inti=0;i<nodes.getLength();i++){
System.out.println("show="+nodes.item(i).getNodeValue());
longendTime=System.currentTimeMillis();
System.out.println("程式運行時間:"+(endTime-startTime)+"ms");
}
}catch(XPathExpressionExceptione){
e.printStackTrace();
}catch(ParserConfigurationExceptione){
e.printStackTrace();
}catch(SAXExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
PS:這裡再提供幾個關於xml操作的線上工具給大家參考使用:
線上XML/JSON互相轉換工具:
http://tools.VeVB.COm/code/xmljson
線上格式化XML/線上壓縮XML:
http://tools.VeVB.COm/code/xmlformat
XML線上壓縮/格式化工具:
http://tools.VeVB.COm/code/xml_format_compress