閱讀784 返回首頁    go 阿裏雲 go 技術社區[雲棲]


開發那點事係列三 - 由XML解析引起的API設計思考

      談起XML解析,大家可能第一反應是DOMSAX模型。沒錯,在Java領域,無論是Dom4j, Jdom,還是XOM,其底層都會依賴具體的解析器引擎(Crimson or Xerces)去做事,具體的實現後麵會有文章陸續探究。今天寫這篇文章的主要目的是想和大家分享自己使用Java SE6StAX API的一些感受,尤其是對其API設計理念的一個思考,沒多少文字,主要是一些啟發性的東東。當然,在你繼續瀏覽之前,希望能熟練掌握以下類庫,有助於更好的和我產生共鳴,哈哈:

     

SAX StAX DOM XSLT
javax.xml.parsers javax.xml.stream javax.xml.parsers javax.xml.transform

javax.xml.stream.events
javax.xml.transform.dom

javax.xml.stream.util
javax.xml.transform.sax



javax.xml.transform.stax



javax.xml.transform.stream

      技術使用論&技術創造論無論你秉持哪種觀點,原理性的、設計性的思維多培養培養,總歸沒有錯的。在對Sun的JAX-× API深度理解的基礎上,希望能拋磚引玉,引發XML API設計上的思考。言歸正傳吧,當我們讀過一些資料(尤其是我後麵列出的文獻資料)過後,我們都會了解到StaxSAX的不同之處:基於流的兩種不同模型的實現PushPull。那麼什麼是pull,什麼又是push,到底哪種好?一句話概括一下(示例代碼如下):Push模型要靠回調或者觀察者模式運作,而Pull模型靠的是迭代器,外加Visitor模式的Filter機製(一種不錯的事件處理鏈模式)。

      SAX(Application code registers a callback, which the SAX parser invokes as it reads the XML:)

FileInputStream fis = new FileInputStream(file);

XMLReader saxXmlReader = XMLReaderFactory.createXMLReader();

// Create callback handler
DefaultHandler handler = new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes) {
        // do something with element
      }
};


// register hander
saxXmlReader.setContentHandler(handler);
saxXmlReader.setErrorHandler(handler);

// control passed to parser...
saxXmlReader.parse(new InputSource(fis));

      StAX(Application code controls parsing directly by iterating over the document using the StAX stream reader)

FileInputStream fis = new FileInputStream(file);

XMLInputFactory factory = (XMLInputFactory)XMLInputFactory.newInstance();
XMLStreamReader staxXmlReader = (XMLStreamReader) factory.createXMLStreamReader(fis);

for (int event = staxXmlReader.next(); event !=   XMLStreamConstants.END_DOCUMENT;
 event = staxXmlReader.next()) {

  
switch (event) {
  case XMLStreamConstants.START_DOCUMENT:
    // do something with element, such as :System.out.println("Start document " + staxXmlReader.getLocalName());
    break;
  case XMLStreamConstants.START_ELEMENT:
    // do something with element, such as :System.out.println("Start element " + staxXmlReader.getLocalName());
    // do something with element, such as :System.out.println("Element text " + staxXmlReader.getElementText());
    break;
  case XMLStreamConstants.END_ELEMENT:
    // do something with element
    break;
  default: 
    // do something with element
    break;
 }}

      看似樸實的設計思路,卻衍生出很多思考。Spring中充滿了鉤子回調函數(類似preXXXHandler/ProcessorpostXXXHandler/Processor),為什麼不做成Listener APIHtmlParser中也充滿了Visitor模式,比起Handler機製,靈活在哪?為什麼說StAX既保證了運行時效率,又把持了元素的上下文狀態。。。諸如此類的問題,在設計我們自己的框架API時,無不需要慎重考慮~

參考文獻:

1.https://www.ibm.com/developerworks/cn/java/j-lo-jse6/

2.https://www.ibm.com/developerworks/cn/xml/x-stax1.html

3.https://www.ibm.com/developerworks/library/x-stax1/index.html  

4.https://www.jcp.org/en/jsr/detail?id=173 

5.https://www.ibm.com/developerworks/cn/xml/x-jaxp/

6.https://www.edankert.com/jaxpimplementations.html

7.https://dom4j.sourceforge.net/dom4j-1.6.1/benchmarks/xpath/index.html



最後更新:2017-04-02 22:16:36

  上一篇:go init/loadView/viewDidLoad/viewDidUnload
  下一篇:go Java連接sqlserver的程序