开发那点事系列三 - 由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时,无不需要慎重考虑~

参考文献:

 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值