首先是我们用到的位于src下面的books.xml
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="COOKING" aaaaaa="111111"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">XQuery Kick Start</title> <author>James McGovern</author> <author>Per Bothner</author> <author>Kurt Cagle</author> <author>James Linn</author> <author>Vaidyanathan Nagarajan</author> <year>2003</year> <price>49.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore>
package com.jadyer.stax; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.stream.EventFilter; import javax.xml.stream.FactoryConfigurationError; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.events.XMLEvent; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * 使用Stax解析XML * @see Stax(Streaming API for XML) * @create Mar 17, 2013 5:30:31 PM * @author 玄玉<http://blog.csdn/net/jadyer> */ public class TestStax { public static void main(String[] args) throws Exception { cursorParseXML(); iteratorParseXML(); filterParseXML(); xpathParseXML(); xmlStreamWriterXML(); transformerModifyXML(); } /** * 基于光标的方式解析XML */ private static void cursorParseXML() throws Exception { XMLInputFactory factory = XMLInputFactory.newInstance(); InputStream is = TestStax.class.getClassLoader().getResourceAsStream("books.xml"); XMLStreamReader reader = factory.createXMLStreamReader(is); while(reader.hasNext()) { int type = reader.next(); //处理不同的节点类型 //处理开始节点,如<bookstore>,<book> if(type == XMLStreamConstants.START_ELEMENT) { String name = reader.getName().toString(); System.out.println("<" + name + ">"); //打印<book category="COOKING" aaaaaa="111111">节点中的第二个属性值aaaaaa if(name.equals("book")){ System.out.println("节点属性值为" + reader.getAttributeName(1) + "=" + reader.getAttributeValue(1)); } if(name.equals("title")) { System.out.println("书籍[" + reader.getElementText() + "]"); } if(name.equals("price")) { System.out.println("的价格为[" + reader.getElementText() + "]"); } //打印文本节点的内容,注意各xml标签中的空白部分也属于文本节点..并且文本节点是没有name的,所以不能getName } else if(type == XMLStreamConstants.CHARACTERS) { System.out.println("文本节点值=[" + reader.getText().trim() + "]"); //处理结束节点,如</book>,</title> } else if(type == XMLStreamConstants.END_ELEMENT) { System.out.println("</" + reader.getName() + ">"); } } //最后处理完了xml,记得关闭..但不能提前关闭,因为Stax是读一点流就解析一点的 is.close(); } /** * 基于迭代模型的方式解析XML */ private static void iteratorParseXML() throws Exception { XMLInputFactory factory = XMLInputFactory.newInstance(); InputStream is = TestStax.class.getClassLoader().getResourceAsStream("books.xml"); XMLEventReader reader = factory.createXMLEventReader(is); int iteratorNum = 0; //统计遍历的次数 while(reader.hasNext()) { XMLEvent event = reader.nextEvent(); if(event.isStartElement()) { //通过XMLEvent判断节点类型 String name = event.asStartElement().getName().toString(); //通过event.asxxx转换节点 if(name.equals("title")) { System.out.print("书籍[" + reader.getElementText() + "]"); } if(name.equals("price")) { System.out.println("的价格为[" + reader.getElementText() + "]"); } } iteratorNum++; } is.close(); System.out.println("本次操作遍历XML的次数合计为[" + iteratorNum + "]次"); } /** * 基于Filter的方式解析XML * @see 可以有效的过滤掉不用进行操作的节点,效率会高一些 */ private static void filterParseXML() throws Exception { XMLInputFactory factory = XMLInputFactory.newInstance(); InputStream is = TestStax.class.getClassLoader().getResourceAsStream("books.xml"); XMLEventReader reader = factory.createFilteredReader(factory.createXMLEventReader(is), new EventFilter() { @Override public boolean accept(XMLEvent event) { if(event.isStartElement()) { String name = event.asStartElement().getName().toString(); if(name.equals("title") || name.equals("price")){ return true; //返回true表示会显示,false表示不显示 } } return false; } }); int iteratorNum = 0; //统计遍历的次数 while(reader.hasNext()) { XMLEvent event = reader.nextEvent(); if(event.isStartElement()) { String name = event.asStartElement().getName().toString(); if(name.equals("title")) { System.out.print("书籍[" + reader.getElementText() + "]"); } if(name.equals("price")) { System.out.println("的价格为[" + reader.getElementText() + "]"); } } iteratorNum++; } is.close(); System.out.println("本次操作遍历XML的次数合计为[" + iteratorNum + "]次"); } /** * 基于XPath的方式解析XML */ private static void xpathParseXML() throws Exception { InputStream is = TestStax.class.getClassLoader().getResourceAsStream("books.xml"); //创建文档处理对象 DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); //通过DocumentBuilder创建doc的文档对象 Document doc = db.parse(is); //创建XPath XPath xpath = XPathFactory.newInstance().newXPath(); //第一个参数就是XPath表达式,第二参数就是文档..这里是查找所有属性为category="WEB"的<book>节点 NodeList list = (NodeList)xpath.evaluate("//book[@category='WEB']", doc, XPathConstants.NODESET); for(int i=0; i<list.getLength(); i++) { Element e = (Element)list.item(i); //由于<book>节点下只会有一个<title>节点,所有这里是item(0) System.out.println(e.getElementsByTagName("title").item(0).getTextContent()); System.out.println(e.getElementsByTagName("price").item(0).getTextContent()); } is.close(); } /** * 使用XMLStreamWriter创建XML */ private static void xmlStreamWriterXML() throws XMLStreamException, FactoryConfigurationError { XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out); xsw.writeStartDocument("GBK","1.0"); xsw.writeEndDocument(); //先写<?xml version="1.0" encoding="GBK"?> String namespaceURI = "http://blog.csdn.net/jadyer"; xsw.writeStartElement("pre", "uesr", namespaceURI); //再写<pre:uesr> xsw.writeStartElement(namespaceURI, "id"); //再写<pre:id> xsw.writeCharacters("1"); //再写1 xsw.writeEndElement(); //再写</pre:id> xsw.writeEndElement(); //再写</pre:uesr> xsw.flush(); xsw.close(); } /** * 使用Transformer更新XML */ private static void transformerModifyXML() throws Exception, TransformerFactoryConfigurationError { InputStream is = TestStax.class.getClassLoader().getResourceAsStream("books.xml"); DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = db.parse(is); XPath xpath = XPathFactory.newInstance().newXPath(); //查找内容含title="Learning XML"的<book>节点 NodeList list = (NodeList)xpath.evaluate("//book[title='Learning XML']", doc, XPathConstants.NODESET); //获取<price>节点,这里只有一个符合条件的<book>节点,所以写成了list.item(0) Element e = (Element)(((Element)list.item(0)).getElementsByTagName("price").item(0)); e.setTextContent("333.9"); Transformer tran = TransformerFactory.newInstance().newTransformer(); tran.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tran.setOutputProperty(OutputKeys.INDENT, "yes"); //让<?xml version=...?>与<bookestore>节点之间换行,默认不换行 //修改节点 tran.transform(new DOMSource(doc), new StreamResult(System.out)); is.close(); } }