1、 DOM解析
DOM的全称是Document Object Model,也即文档对象模型。DOM解析会将XML文档以对象树的方式存入内存,因此,DOM解析内存消耗巨大。当然由于DOM解析将XML以节点树的方式调入内存,所以对文档进行增删改查(crud)比较方便。DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。
-------------------------book.xml----------------------------------------------- <?xml version="1.0" encoding="UTF-8" standalone="no"?> <书架> <书> <书名>javaweb</书名> <作者>xiehe</作者> <售价>889.00元</售价> </书> <书> <书名>javaweb2</书名> <作者>hehe</作者> <售价>8.00元</售价> </书> </书架> ------------------------------------------------------------------------------------ package it.xiehe.xml; import java.io.FileOutputStream; import java.text.AttributedCharacterIterator.Attribute; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Demo02 { //1、读取xml文档内容 @Test public void read() throws Exception{ DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=factory.newDocumentBuilder(); Document document=builder.parse("src/it/xiehe/xml/book.xml"); NodeList list=document.getElementsByTagName("书名"); Node node= list.item(0); String content= node.getTextContent(); System.out.println(content); } //递归遍历节点 @Test public void read1() throws Exception{ DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=factory.newDocumentBuilder(); Document document=builder.parse("src/it/xiehe/xml/book.xml"); Node node=document.getElementsByTagName("书架").item(0); list(node); } private void list(Node node) { System.out.println(node.getTextContent()); NodeList list=node.getChildNodes(); for(int i=0;i<list.getLength();i++){ Node child=list.item(i); list(child); } } //增加一个节点 @Test public void add() throws Exception{ //1、获取document DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=factory.newDocumentBuilder(); Document document=builder.parse("src/it/xiehe/xml/book.xml"); //2、增加节点 <售价>57.00元</售价> //1>创建节点 Element piece=document.createElement("售价"); piece.setTextContent("57.00元"); //2>把创建的节点挂到第一本书上 Element book=(Element) document.getElementsByTagName("书").item(0); book.appendChild(piece); //3将修改的xml文件回写 TransformerFactory tffactory=TransformerFactory.newInstance(); Transformer tf=tffactory.newTransformer(); tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/it/xiehe/xml/book.xml"))); } }
2、SAX解析
SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
需要注意的是,SAX解析XML文档时,空白不能忽略。
package it.xiehe.xml; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.sax.SAXTransformerFactory; import org.junit.Test; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; public class DemoSAX { @Test public void test01() throws Exception, Exception { // 1 创建sax工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); // 2 得到解析器 SAXParser parser = factory.newSAXParser(); // 3 得到读取器 XMLReader reader = parser.getXMLReader(); // 4 设置内容处理器 // 不同的功能对应不同的处理器,一般通过继承DefaultHandler覆盖其中的方法 reader.setContentHandler(new ListHandler()); // 5 读取xml文件内容 reader.parse("src/Book.xml"); } } //1、打印出xml文件所有内容 //通过实现ContentHandler接口对XML文档进行处理 class ListHandler implements ContentHandler{ @Override public void setDocumentLocator(Locator locator) { // TODO Auto-generated method stub } @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub } @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { // TODO Auto-generated method stub } @Override public void endPrefixMapping(String prefix) throws SAXException { // TODO Auto-generated method stub } @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { //这里对获取到的元素进行处理,暂时先输出吧! System.out.println("<"+qName+">"); for(int i=0;atts!=null&&i<atts.getLength();i++){ String name=atts.getQName(i); String value=atts.getValue(i); System.out.println(name+"="+value); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub System.out.println("<"+qName+">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub System.out.println(new String(ch,start,length)); } @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub } @Override public void processingInstruction(String target, String data) throws SAXException { // TODO Auto-generated method stub } @Override public void skippedEntity(String name) throws SAXException { // TODO Auto-generated method stub }} -------------------------------获得XML文档数据并且封装到对象中---------------------- package it.xiehe.xml; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.sax.SAXTransformerFactory; import org.junit.Test; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; public class Demo03SAX { @Test public void test01() throws Exception, Exception { // 1 创建sax工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); // 2 得到解析器 SAXParser parser = factory.newSAXParser(); // 3 得到读取器 XMLReader reader = parser.getXMLReader(); // 4 设置内容处理器 BeanListHandler handler=new BeanListHandler(); reader.setContentHandler(handler); // 5 读取xml文件内容 reader.parse("src/it/xiehe/xml/book.xml"); List<book> list=handler.getBook(); for(book b:list){ System.out.println(b); } } } // 3、打印出xml文件所有内容用book对象封装 //这里通过继承DefaultHandler类覆盖里面我们需要的方法实现想要的功能 class BeanListHandler extends DefaultHandler { private String TagContent;//记录标签内容 private book b;// List list = new ArrayList();//存储book对象 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { TagContent = qName; if ("书".equals(TagContent)) { b = new book(); } } public List getBook() { return list; } @Override public void characters(char[] ch, int start, int length) throws SAXException { if ("书名".equals(TagContent)) { String name = new String(ch, start, length); b.setName(name); } if ("作者".equals(TagContent)) { String author = new String(ch, start, length); b.setAuthor(author); } if ("售价".equals(TagContent)) { String price = new String(ch, start, length); b.setPrice(price); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("书".equals(qName)) { list.add(b); b=null; } //此处需要重置,不然会有错误的 TagContent = null; } } ---------------------------------book类封装------------------------------------------- package it.xiehe.xml; public class book { private String name; private String author; private String price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } @Override public String toString() { return "书名:"+name+" 作者:"+author+" 价格:"+price; } }
2、dom4j
对主流的Java XML API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。使用Dom4j时,可以通过查看他本身的的文档快速入门使用,在使用过程中尤其注意中文乱码问腿。
package it.xiehe.xml; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.OutputStreamWriter; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.junit.Test; public class DemoDom4j { // 使用Dom4j读取xml中的内容:<书名>javaweb1</书名> @Test public void read() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/it/xiehe/xml/book.xml")); // 获得根节点 Element root = document.getRootElement(); // Dom4j比较笨,需要从根结点一层层往下取数据 // 当xml中有属性 (attribute)取法与之类似 Element book = (Element) root.elements("书").get(0);// 此处从list集合中取出,所以需要类型强转 String name = book.element("书名").getText(); System.out.println(name); } // 增加第一本书的售价2:<售价>88.00元</售价> // 中文乱码问题有待解决 @Test public void add() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/it/xiehe/xml/book.xml")); // 获得根节点 Element root = document.getRootElement(); // 在<书>节点下增加一个节点<售价>到内存中去 root.element("书").addElement("售价").addText("88.00元"); // 从内存中写回xml文件中 // XMLWriter 将文件交给Filewriter写入xml文档中,后者自动调用本地编码GB2312码编码产生乱码 /* * XMLWriter writer = new XMLWriter(new FileWriter( * "src/it/xiehe/xml/book.xml")); */ /* * //查询api可以知道,OutputStreamWriter 可以指定编码方式,所以使用它指定UTF-8 XMLWriter writer * = new XMLWriter(new OutputStreamWriter( new * FileOutputStream("src/it/xiehe/xml/book.xml"), "UTF-8")); * writer.write(document); writer.close(); */ // 在开发中,常用的方法是设置一个格式化输出器 // Pretty print the document to System.out OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream( "src/it/xiehe/xml/book.xml"), format); writer.write(document); writer.close(); } }
下面是使用dom4j增删改查的小例子
package it.xiehe.xml; import java.io.File; import java.io.FileOutputStream; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.junit.Test; public class DomeDom4j02 { // 将<售价>888.00元</售价>添加到指定位置(第二本书的作者后面) @Test public void add() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/it/xiehe/xml/book.xml")); // 获得根节点 Element root = document.getRootElement(); Element book = (Element) root.elements("书").get(1); List list = book.elements();// [书名 作者 售价] // 创建新节点 Element price = DocumentHelper.createElement("售价"); price.setText("888.00元"); // 添加到list集合中指定位置 list.add(2, price); // 更新到xml文档中 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream( "src/it/xiehe/xml/book.xml"), format); writer.write(document); writer.close(); } // 删除刚刚添加的节点(获得该节点的爸爸节点删除自己) @Test public void delete() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/it/xiehe/xml/book.xml")); // 获得根节点 Element root = document.getRootElement(); Element book = (Element) root.elements("书").get(1); Element price = (Element) book.elements("售价").get(0); price.getParent().remove(price); // 更新到xml文档中 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream( "src/it/xiehe/xml/book.xml"), format); writer.write(document); writer.close(); } // 更新节点信息第一本书<售价>88.00元</售价>变为<售价>66.00元</售价> @Test public void update() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File("src/it/xiehe/xml/book.xml")); // 获得根节点 Element root = document.getRootElement(); Element book = (Element) root.elements("书").get(0); Element price = (Element) book.elements("售价").get(1); price.setText("66.00元"); // 更新到xml文档中 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); XMLWriter writer = new XMLWriter(new FileOutputStream( "src/it/xiehe/xml/book.xml"), format); writer.write(document); writer.close(); } }
时间: 2024-08-03 05:03:39