欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JAVA通過XPath解析XML性能比較詳解

 更新時間:2017年02月16日 14:12:10   作者:王中秋  
本篇文章主要介紹了JAVA通過XPath解析XML性能比較詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

最近在做一個小項目,使用到XML文件解析技術(shù),通過對該技術(shù)的了解和使用,總結(jié)了以下內(nèi)容。

1 XML文件解析的4種方法

通常解析XML文件有四種經(jīng)典的方法?;镜慕馕龇绞接袃煞N,一種叫SAX,另一種叫DOM。SAX是基于事件流的解析,DOM是基于XML文檔樹結(jié)構(gòu)的解析。在此基礎(chǔ)上,為了減少DOM、SAX的編碼量,出現(xiàn)了JDOM,其優(yōu)點是,20-80原則(帕累托法則),極大減少了代碼量。通常情況下JDOM使用時滿足要實現(xiàn)的功能簡單,如解析、創(chuàng)建等要求。但在底層,JDOM還是使用SAX(最常用)、DOM、Xanan文檔。另外一種是DOM4J,是一個非常非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強大和極端易用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的 Java 軟件都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。

2 XPath簡單介紹

XPath 是一門在 XML 文檔中查找信息的語言。XPath 用于在 XML 文檔中通過元素和屬性進行導(dǎo)航,并對元素和屬性進行遍歷。XPath 是 W3C XSLT 標準的主要元素,并且 XQuery 和 XPointer 同時被構(gòu)建于 XPath 表達之上。因此,對 XPath 的理解是很多高級 XML 應(yīng)用的基礎(chǔ)。XPath非常類似對數(shù)據(jù)庫操作的SQL語言,或者說JQuery,它可以方便開發(fā)者抓起文檔中需要的東西。其中DOM4J也支持XPath的使用。

3 DOM4J使用XPath

DOM4J使用XPath解析XML文檔是,首先需要在項目中引用兩個JAR包:

dom4j-1.6.1.jar:DOM4J軟件包,下載地址http://sourceforge.net/projects/dom4j/;

jaxen-xx.xx.jar:通常不添加此包,會引發(fā)異常(java.lang.NoClassDefFoundError: org/jaxen/JaxenException),下載地址http://www.jaxen.org/releases.html。

3.1 命名空間(namespace)的干擾

在處理由excel文件或其他格式文件轉(zhuǎn)換的xml文件時,通常會遇到通過XPath解析得不到結(jié)果的情況。這種情況通常是由于命名空間的存在導(dǎo)致的。以下述內(nèi)容的XML文件為例,通過XPath=" // Workbook/ Worksheet / Table / Row[1]/ Cell[1]/Data[1] "進行簡單的檢索,通常是沒有結(jié)果出現(xiàn)的。這就是由于命名空間namespace(xmlns="urn:schemas-microsoft-com:office:spreadsheet")導(dǎo)致的。

<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()函數(shù)):使用XPath語法中自帶的local-name() 和 namespace-uri() 指定你要使用的節(jié)點名和命名空間。 XPath表達式書寫較為麻煩。

第二種方法(read2()函數(shù)):設(shè)置XPath的命名空間,利用setNamespaceURIs()函數(shù)。

第三種方法(read3()函數(shù)):設(shè)置DocumentFactory()的命名空間 ,使用的函數(shù)是setXPathNamespaceURIs()。二和三兩種方法的XPath表達式書寫相對簡單。

第四種方法(read4()函數(shù)):方法和第三種一樣,但是XPath表達式不同(程序具體體現(xiàn)),主要是為了檢驗XPath表達式的不同,主要指完整程度,是否會對檢索效率產(chǎn)生影響。(以上四種方法均通過DOM4J結(jié)合XPath對XML文件進行解析)

第五種方法(read5()函數(shù)):使用DOM結(jié)合XPath對XML文件進行解析,主要是為了檢驗性能差異。

沒有什么能夠比代碼更能說明問題的了!果斷上代碼!

package XPath;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * DOM4J DOM XML XPath
 * @author hao
 */
public class TestDom4jXpath {
  public static void main(String[] args) {
    read1();
    read2();
    read3();
    read4();//read3()方法一樣,但是XPath表達式不同
    read5();
  }
  
  public static void read1() {
    /*
     * use local-name() and namespace-uri() in XPath
     */
    try {
      long startTime=System.currentTimeMillis();
      SAXReader reader = new SAXReader();
      InputStream in = TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath\\XXX.xml");
      Document doc = reader.read(in);
      /*String xpath ="http://*[local-name()='Workbook' and namespace-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]";*/
      String xpath ="http://*[local-name()='Row'][4]/*[local-name()='Cell'][3]/*[local-name()='Data'][1]";
      System.err.println("=====use local-name() and namespace-uri() in XPath====");
      System.err.println("XPath:" + xpath);
      @SuppressWarnings("unchecked")
      List<Element> list = doc.selectNodes(xpath);
      for(Object o:list){ 
        Element e = (Element) o; 
        String show=e.getStringValue();
        System.out.println("show = " + show); 
      long endTime=System.currentTimeMillis();
      System.out.println("程序運行時間: "+(endTime-startTime)+"ms");
      } 
    } catch (DocumentException e) {
      e.printStackTrace();
    }
  }
  
  public static void read2() {
    /*
     * set xpath namespace(setNamespaceURIs)
     */
    try {
      long startTime=System.currentTimeMillis();
      Map map = new HashMap();
      map.put("Workbook","urn:schemas-microsoft-com:office:spreadsheet");
      SAXReader reader = new SAXReader();
      InputStream in = TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath\\XXX.xml");
      Document doc = reader.read(in);
      String xpath ="http://Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]";
      System.err.println("=====use setNamespaceURIs() to set xpath namespace====");
      System.err.println("XPath:" + xpath);
      XPath x = doc.createXPath(xpath);
      x.setNamespaceURIs(map);
      @SuppressWarnings("unchecked")
      List<Element> list = x.selectNodes(doc);
      for(Object o:list){ 
        Element e = (Element) o; 
        String show=e.getStringValue();
        System.out.println("show = " + show);  
      long endTime=System.currentTimeMillis();
      System.out.println("程序運行時間: "+(endTime-startTime)+"ms");
      } 
    } catch (DocumentException e) {
      e.printStackTrace();
    }
  }
  
  public static void read3() {
    /*
     * set DocumentFactory() namespace(setXPathNamespaceURIs)
     */
    try {
      long startTime=System.currentTimeMillis();
      Map map = new HashMap();
      map.put("Workbook","urn:schemas-microsoft-com:office:spreadsheet");
      SAXReader reader = new SAXReader();
      InputStream in = TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath\\XXX.xml");
      reader.getDocumentFactory().setXPathNamespaceURIs(map);
      Document doc = reader.read(in);
      String xpath ="http://Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]";
      System.err.println("=====use setXPathNamespaceURIs() to set DocumentFactory() namespace====");
      System.err.println("XPath:" + xpath);
      @SuppressWarnings("unchecked")
      List<Element> list = doc.selectNodes(xpath);
      for(Object o:list){ 
        Element e = (Element) o; 
        String show=e.getStringValue();
        System.out.println("show = " + show);
      long endTime=System.currentTimeMillis();
      System.out.println("程序運行時間: "+(endTime-startTime)+"ms");  
      } 
    } catch (DocumentException e) {
      e.printStackTrace();
    }
  }
  
  public static void read4() {
    /*
     * 同read3()方法一樣,但是XPath表達式不同
     */
    try {
      long startTime=System.currentTimeMillis();
      Map map = new HashMap();
      map.put("Workbook","urn:schemas-microsoft-com:office:spreadsheet");
      SAXReader reader = new SAXReader();
      InputStream in = TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath\\XXX.xml");
      reader.getDocumentFactory().setXPathNamespaceURIs(map);
      Document doc = reader.read(in);
      String xpath ="http://Workbook:Worksheet/Workbook:Table/Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]";
      System.err.println("=====use setXPathNamespaceURIs() to set DocumentFactory() namespace====");
      System.err.println("XPath:" + xpath);
      @SuppressWarnings("unchecked")
      List<Element> list = doc.selectNodes(xpath);
      for(Object o:list){ 
        Element e = (Element) o; 
        String show=e.getStringValue();
        System.out.println("show = " + show);
      long endTime=System.currentTimeMillis();
      System.out.println("程序運行時間: "+(endTime-startTime)+"ms");  
      } 
    } catch (DocumentException e) {
      e.printStackTrace();
    }
  }
  
  public static void read5() {
    /*
     * DOM and XPath
     */
    try {
      long startTime=System.currentTimeMillis();
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      dbf.setNamespaceAware(false);
      DocumentBuilder builder = dbf.newDocumentBuilder();
      InputStream in = TestDom4jXpath.class.getClassLoader().getResourceAsStream("XPath\\XXX.xml");
      org.w3c.dom.Document doc = builder.parse(in);
      XPathFactory factory = XPathFactory.newInstance();
      javax.xml.xpath.XPath x = factory.newXPath();
      //選取所有class元素的name屬性
      String xpath = "http://Workbook/Worksheet/Table/Row[4]/Cell[3]/Data[1]";
      System.err.println("=====Dom XPath====");
      System.err.println("XPath:" + xpath);
      XPathExpression expr = x.compile(xpath);
      NodeList nodes = (NodeList)expr.evaluate(doc, XPathConstants.NODE);
      for(int i = 0; i<nodes.getLength();i++) {
        System.out.println("show = " + nodes.item(i).getNodeValue());
      long endTime=System.currentTimeMillis();
      System.out.println("程序運行時間: "+(endTime-startTime)+"ms");
      }
    } catch(XPathExpressionException e) {
      e.printStackTrace();
    } catch(ParserConfigurationException e) {
      e.printStackTrace();
    } catch(SAXException e) {
      e.printStackTrace();
    } catch(IOException e) {
      e.printStackTrace();
    }
  }
}

3.3 不同方法的性能比較

為了比較幾種方法的解析性能,實驗過程中使用了6M以上大小,7萬行以上的XML文件(XXX.xml)進行10輪測試,如下所述:

圖1 XPath使用性能對比

方法名稱

平均運行時間

XPath表達式

read1()

1663ms

//*[local-name()='Row'][4]/*[local-name()='Cell'][3]/*[local-name()='Data'][1]

read2()

2184ms

//Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]

read3()

601ms

//Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]

read4()

472ms

//Workbook:Worksheet/Workbook:Table/Workbook:Row[4]/Workbook:Cell[3]/Workbook:Data[1]

read5()

1094ms

//Workbook/Worksheet/Table/Row[4]/Cell[3]/Data[1]

表1 平均性能統(tǒng)計

由以上性能對比可知:

1、read4()方法運行時間最短,即運用DOM4J方法調(diào)用全路徑(從根節(jié)點出發(fā))XPath表達式解析XML文件耗時最短;

2、運用DOM解析方法所使用的XPath表達式最為簡單(可以寫作//Row[4]/Cell[3]/Data[1]),因DOM中可以通過setNamespaceAware(false)方法使命名空間失效。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java程序員必須知道的5個JVM命令行標志

    Java程序員必須知道的5個JVM命令行標志

    這篇文章主要介紹了每個Java程序員必須知道的5個JVM命令行標志,需要的朋友可以參考下
    2015-03-03
  • Spring?Boot如何利用攔截器加緩存完成接口防刷操作

    Spring?Boot如何利用攔截器加緩存完成接口防刷操作

    流的需求出現(xiàn)在許多常見的場景中,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot如何利用攔截器加緩存完成接口防刷操作的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • spring-shiro權(quán)限控制realm實戰(zhàn)教程

    spring-shiro權(quán)限控制realm實戰(zhàn)教程

    這篇文章主要介紹了spring-shiro權(quán)限控制realm實戰(zhàn)教程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • springboot創(chuàng)建文件夾失敗的解決

    springboot創(chuàng)建文件夾失敗的解決

    這篇文章主要介紹了springboot創(chuàng)建文件夾失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java中 String和StringBuffer的區(qū)別實例詳解

    java中 String和StringBuffer的區(qū)別實例詳解

    這篇文章主要介紹了java中 String和StringBuffer的區(qū)別實例詳解的相關(guān)資料,一個小的例子,來測試String和StringBuffer在時間和空間使用上的差別,需要的朋友可以參考下
    2017-04-04
  • 詳解基于MVC的數(shù)據(jù)查詢模塊進行模糊查詢

    詳解基于MVC的數(shù)據(jù)查詢模塊進行模糊查詢

    這篇文章主要介紹了Java基于MVC的數(shù)據(jù)查詢模塊進行模糊查詢,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • SpringBoot集成quartz實現(xiàn)定時任務(wù)詳解

    SpringBoot集成quartz實現(xiàn)定時任務(wù)詳解

    最為常用定時任務(wù)框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不僅支持單實例方式還支持分布式方式。本文主要介紹Quartz,基礎(chǔ)的Quartz的集成案例本,以及實現(xiàn)基于數(shù)據(jù)庫的分布式任務(wù)管理和控制job生命周期
    2022-08-08
  • 說說字符串轉(zhuǎn) OffSetDateTime 你真的會用嗎

    說說字符串轉(zhuǎn) OffSetDateTime 你真的會用嗎

    這篇文章主要介紹了字符串轉(zhuǎn) OffSetDateTime 你真的會用嗎?具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java基于Apache FTP點斷續(xù)傳的文件上傳和下載

    java基于Apache FTP點斷續(xù)傳的文件上傳和下載

    本篇文章主要介紹了java基于Apache FTP點斷續(xù)傳的文件上傳和下載,利用FTP實現(xiàn)文件的上傳和下載,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2016-11-11
  • Java中replace、replaceAll和replaceFirst函數(shù)的用法小結(jié)

    Java中replace、replaceAll和replaceFirst函數(shù)的用法小結(jié)

    相信會java的同學(xué)估計都用過replace、replaceAll、replaceFirst這三個函數(shù),可是,我們真的懂他們嗎?下面通過這篇文章大家再來好好學(xué)習(xí)學(xué)習(xí)下這幾個函數(shù)。
    2016-09-09

最新評論