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相比较而言有以下优点:
- 从XMLEvent创造的对象是不可更改的。能用于array,list,map。
- 可以继承XMLEvent。
- 更容易添加和删除事件。
如果内存受限或是要求高performance,优先选择Cursor API;其他情况下尽量使用Event Iterator API。
XMLInputFactory用于创建xml流读取。XMLInputFactory.newInstance按照以下步骤决定XMLInputFactory实例:
- 使用javax.xml.stream.XMLInputFactory系统属性;
- 使用JRE下lib/xml.stream.properties文件;
- 使用Services API,在META-INF/services/javax.xml.stream.XMLInputFactory里查找;
- 使用系统默认的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)