JDK6的新特性之三:理解StAX
StAX(JSR173)是JDK6.0中除了DOM和SAX之外的又一种处理XML文档的API
StAX的来历
在JAXP1.3(JSR206)有两种处理XML文档的方法:DOM(DocumentObjectModel)和SAX(SimpleAPIforXML).由于JDK6.0中的JAXB2(JSR222)和JAX-WS2.0(JSR224)都会用到StAX所以Sun决定把StAX加入到JAXP家族当中来,并将JAXP的版本升级到1.4(JAXP1.4是JAXP1.3的维护版本).JDK6里面JAXP的版本就是1.4.
StAX简介
StAX是TheStreamingAPIforXML的缩写,一种利用拉模式解析(pull-parsing)XML文档的API.StAX通过提供一种基于事件迭代器(Iterator)的API让程序员去控制xml文档解析过程,程序遍历这个事件迭代器去处理每一个解析事件,解析事件可以看做是程序拉出来的,也就是程序促使解析器产生一个解析事件然后处理该事件,之后又促使解析器产生下一个解析事件,如此循环直到碰到文档结束符;SAX也是基于事件处理xml文档,但却是用推模式解析,解析器解析完整个xml文档后,才产生解析事件,然后推给程序去处理这些事件;DOM采用的方式是将整个xml文档映射到一颗内存树,这样就可以很容易地得到父节点和子结点以及兄弟节点的数据,但如果文档很大,将会严重影响性能。下面是这几种API的比较(转载自
http://www.blogjava.net/hsith/archive/2006/06/29/55817.html)
XMLParserAPIFeatureSummaryFeatureStAXSAXDOMTrAX
APITypePull,streamingPush,streamingInmemorytreeXSLTRule
EaseofUseHighMediumHighMedium
XPathCapabilityNoNoYesYes
CPUandMemoryEfficiencyGoodGoodVariesVaries
ForwardOnlyYesYesNoNo
ReadXMLYesYesYesYes
WriteXMLYesNoYesYes
Create,Read,Update,DeleteNoNoYesNo
StAX代码演示
下面代码演示了如何通过StAX读取xml文档和生成xml文档
publicclassStaxTester{
publicstaticvoidmain(String[]args)throwsXMLStreamException,FileNotFoundException{
readXMLByStAX();//用XMLEventReader解析xml文档
writeXMLByStAX();//用XMLStreamWriter写xml文档
}
privatestaticvoidreadXMLByStAX()throwsXMLStreamException,FileNotFoundException{
XMLInputFactoryxmlif=XMLInputFactory.newInstance();
XMLEventReaderxmler=xmlif.createXMLEventReader(StaxTester.class.getResourceAsStream("test.xml"));
XMLEventevent;
StringBufferparsingResult=newStringBuffer();
while(xmler.hasNext()){
event=xmler.nextEvent();
if(event.isStartElement()){//如果解析的是起始标记
StartElementse=event.asStartElement();
parsingResult.append("<");
parsingResult.append(se.getName());
if(se.getName().getLocalPart().equals("catalog")){
parsingResult.append("id=/"");
parsingResult.append(se.getAttributeByName(newQName("id")).getValue());
parsingResult.append("/"");
}
parsingResult.append(">");
}elseif(event.isCharacters()){//如果解析的是文本内容
parsingResult.append(event.asCharacters().getData());
}elseif(event.isEndElement()){//如果解析的是结束标记
parsingResult.append("</");
parsingResult.append(event.asEndElement().getName());
parsingResult.append(">");
}
}
System.out.println(parsingResult);
}
privatestaticvoidwriteXMLByStAX()throwsXMLStreamException,FileNotFoundException{
XMLOutputFactoryxmlof=XMLOutputFactory.newInstance();
XMLStreamWriterxmlw=xmlof.createXMLStreamWriter(newFileOutputStream("output.xml"));
//写入默认的XML声明到xml文档
xmlw.writeStartDocument();
xmlw.writeCharacters("/n");
//写入注释到xml文档
xmlw.writeComment("testingcomment");
xmlw.writeCharacters("/n");
//写入一个catalogs根元素
xmlw.writeStartElement("catalogs");
xmlw.writeNamespace("myNS","http://blog.csdn.net/Chinajash");
xmlw.writeAttribute("owner","Chinajash");
xmlw.writeCharacters("/n");
//写入子元素catalog
xmlw.writeStartElement("http://blog.csdn.net/Chinajash","catalog");
xmlw.writeAttribute("id","007");
xmlw.writeCharacters("Apparel");
//写入catalog元素的结束标签
xmlw.writeEndElement();
//写入catalogs元素的结束标签
xmlw.writeEndElement();
//结束XML文档
xmlw.writeEndDocument();
xmlw.close();
}
}
test.xml文件内容如下:
<?xmlversion="1.0"encoding="UTF-8"?>
<catalogs>
<catalogid="001">Book</catalog>
<catalogid="002">Video</catalog>
</catalogs>
运行上面程序后,控制台输出如下:
<catalogs>
<catalogid="001">Book</catalog>
<catalogid="002">Video</catalog>
</catalogs>
运行上面程序后,产生的output.xml文件如下:
<?xmlversion="1.0"?>
<!--testingcomment-->
<catalogsxmlns:myNS="http://blog.csdn.net/Chinajash"owner="Chinajash">
<myNS:catalogid="007">Apparel</myNS:catalog>
</catalogs>