Java处理XML的方法

  • DOM(Document Object Model)  API: 顾名思义,基于dom 书读写xml。
public static void main(String[] args) throws SAXException, IOException,
            ParserConfigurationException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setIgnoringElementContentWhitespace(true);
        // dbf.setNamespaceAware(true);
        // dbf.setValidating(true);
        DocumentBuilder db = dbf.newDocumentBuilder();

        OutputStreamWriter errorWriter = new OutputStreamWriter(System.err,
                "UTF-8");
        db.setErrorHandler(new MyErrorHandler(
                new PrintWriter(errorWriter, true)));
        Document doc = db.parse(new File("resources/dom_example.xml"));
        Element node = doc.getDocumentElement();
        traverse(node, 0);
        traverse1(node, 0);
    }

    private static void traverse(Node node, int deep) {
        if (null == node) {
            return;
        }
        Node sibling = node;
        while (null != sibling) {
            if (Node.ELEMENT_NODE == sibling.getNodeType()) {
                printNode(sibling, deep);
                traverse(sibling.getFirstChild(), deep + 1);
            }
            sibling = sibling.getNextSibling();
        }
    }

 

 这里需要特别注意White Space。 参考: http://www.oracle.com/technetwork/articles/wang-whitespace-092897.html

    除了JDK自己的dom实现外,常用的dom库有DOM4J。    

  • SAX(Simple API for XML) API: 按顺序读取xml。该api只能读取xml文件。它提供一种基于Push-Parsing Model的事件驱动方式解析xml。

    既然是Push parsing,我们需要实现Handler来(ContentHandler, ErrorHandler, DTDHandler, etc.)对获取的事件进行处理。通常我们继承DefaultHandler。

    

    SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setNamespaceAware(true);
        SAXParser saxParser = spf.newSAXParser();
        XMLReader xmlReader = saxParser.getXMLReader();
        xmlReader.setContentHandler(new SAXLocalNameCount());
        xmlReader.setErrorHandler(new MyErrorHandler(System.err));
        xmlReader.parse("sax_example.xml");

 

    DOM和SAX都是1.6之前的api,因此,最好不要再使用。

    从1.6开始,为了提高效率,提供了几种新的api用于处理xml:

  • Stax(Streaming API for XML):一种基于Pull-Parsing model的xml处理api。有关XML Pull的内容可以参考http://www.xmlpull.org/v1/download/unpacked/doc/quick_intro.html。

    

    Stax API分为Cursor API和Event Iterator API。

      Cursor API提供一个前向Cursor遍历xml。主要包括2个接口:

        XMLStreamReader

        XMLStreamWriter:

      Event Iterator API将xml流看成事件对象。解析器(Parser)通过pull方式获取事件。主要包括以下接口:

        XMLEvent

        XMLEventReader

        XMLEventWriter

      Event Iterator API与Cursor API相比较而言有以下优点:

      1. 从XMLEvent创造的对象是不可更改的。能用于array,list,map。  
      2. 可以继承XMLEvent。
      3. 更容易添加和删除事件。

      如果内存受限或是要求高performance,优先选择Cursor API;其他情况下尽量使用Event Iterator API。

      XMLInputFactory用于创建xml流读取。XMLInputFactory.newInstance按照以下步骤决定XMLInputFactory实例:

      1. 使用javax.xml.stream.XMLInputFactory系统属性;
      2. 使用JRE下lib/xml.stream.properties文件;
      3. 使用Services API,在META-INF/services/javax.xml.stream.XMLInputFactory里查找;
      4. 使用系统默认的XMLInputFactory实现;   

      XMLOutputFactory用于创建xml流写入。

      XMLEventFactory用于创建事件。

      XMLStreamReader:

              

 XMLInputFactory f = XMLInputFactory.newInstance();
 XMLStreamReader r = f.createXMLStreamReader( ... );
 while(r.hasNext()) {
     r.next();
 }

      XMLEventReader:

      XMLStreamWriter:

      XMLEventWriter:

 

      报告CDATA Event:javax.xml.stream.XMLStreamReader 默认不报告CDATA事件。如果需要的话,可以按以下配置XMLInputFactory:

XMLInputFactory factory = XMLInptuFactory.newInstance();
factory.setProperty("report-cdata-event", Boolean.TRUE);

      具体例子可以参考:http://docs.oracle.com/javase/tutorial/jaxp/stax/example.html

      

    关于Stax和其他Xml api的对比可以参照http://docs.oracle.com/javase/tutorial/jaxp/stax/why.html

 

  • JAXB(Java Architecture for XML Binding)
posted @ 2015-09-21 16:07  码农大刘  阅读(565)  评论(0编辑  收藏  举报