XML解析的两种方式:DOM方式和SAX方式

来源:互联网 发布:网络摄像头平台 编辑:程序博客网 时间:2024/05/29 02:30

DOM:Document ObjectModel,文档对象模型。这种方式是W3C推荐的处理XML的一种方式。
SAX:Simple API for XML。这种方式不是官方标准,属于开源社区XML-DEV,几乎所有的XML解析器都支持它。

一、DOM解析:

         一次性把xml文档加载成Document树,通过Document对象得到节点对象,通过节点对象访问xml文档内容(标签,属性,文本,注释)。

a)JAXP解析:是SUN公司推出的解析标准实现。

                      以book.xml为例讲解。

<书架>     <书>          <书名>计算机网络</书名>          <作者>张三</作者>          <售价>100</售价>     </书>     <书>          <书名>数据结构</书名>          <作者>李四</作者>          <售价>80</售价>     </书></书架>
获得JAXP中的DOM解析器
l、调用DocumentBuilderFactory.newInstance() 方法得到创建DOM 解析器的工厂。
2、调用工厂对象的newDocumentBuilder方法得到DOM 解析器对象。
3、调用DOM 解析器对象的parse() 方法解析XML 文档,得到代表整个文档的Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。
// 创建解析器对象
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();// 加载XML文档Document document = db.parse("src/book.xml");

1、得到某个具体的节点内容 : eg: 拿到计算机网络的售价

public static void test1(Document document) {// 拿到所有售价节点NodeList nl = document.getElementsByTagName("售价");// 获得计算机网络的售价节点Node n = nl.item(1);// 获取售价文本System.out.println(n.getTextContent());}
2、遍历所有元素节点
public static void test2(Node node) {// 对node节点进行循环NodeList nl = node.getChildNodes();// 循环判断for (int i = 0; i < nl.getLength(); i++) {Node n = nl.item(i);if (n.getNodeType() == Node.ELEMENT_NODE) {// 说明此节点就是标签节点System.out.println(n.getNodeName());test2(n);}}}
3、修改某个元素节点的主体内容 eg: 修改计算机网络的售价为80
public static void test3(Document document) throws Exception {// 拿到所有售价节点NodeList nl = document.getElementsByTagName("售价");// 获得计算机网络的售价节点Node n = nl.item(1);// 修改主体内容n.setTextContent("80");// 将修改的结果保存到硬盘上Transformer tf = TransformerFactory.newInstance().newTransformer();tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));}
4、向指定元素节点中增加子元素节点:eg:给数据结构的售价增加一个内部价节点 :50
public static void test4(Document document) throws Exception {// 拿到所有售价节点NodeList nl = document.getElementsByTagName("售价");// 获得数据结构的售价节点Node n = nl.item(0);// 创建新的节点Element el = document.createElement("内部价");// 设置节点的主体内容el.setTextContent("50");// 将内部价节点挂接到售价几点上n.appendChild(el);// 将修改的结果保存到硬盘上Transformer tf = TransformerFactory.newInstance().newTransformer();tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));}
5、向指定元素节点上增加同级元素节点 : eg:给数据结构的售价增加一个批发价节点 :60
public static void test5(Document document) throws Exception {// 拿到所有书节点NodeList nl = document.getElementsByTagName("书");// 获得数据结构的书节点Node n = nl.item(0);// 创建批发价节点Element el = document.createElement("批发价");// 设置节点的主体内容el.setTextContent("60");// 将内部价节点挂接到书点上n.appendChild(el);// 将修改的结果保存到硬盘上Transformer tf = TransformerFactory.newInstance().newTransformer();tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));}
6、删除指定元素节点 eg: 删除内部价节点
public static void test6(Document document) throws Exception {// 拿到所有内部价节点NodeList nl = document.getElementsByTagName("内部价");// 拿到数据结构的内部价节点Node node = nl.item(0);// 父亲干掉儿子node.getParentNode().removeChild(node);// 将修改的结果保存到硬盘上Transformer tf = TransformerFactory.newInstance().newTransformer();tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));}
7、操作XML文件属性: eg: 给数据结构的书几点增加一个属性: ISBN : "小小程序员"
public static void test7(Document document) throws Exception {// 拿到所有书节点NodeList nl = document.getElementsByTagName("书");// 获得数据结构的书节点Node n = nl.item(0);// 增加一个属性((Element) n).setAttribute("ISBN", "小小程序员");// 将修改的结果保存到硬盘上Transformer tf = TransformerFactory.newInstance().newTransformer();tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));}

b)Dom4J解析:

          i.第一步:读取XML文档信息,生成document对象

1.读取XML文件,获得document对象

<p></p><p>SAXReader reader = new SAXReader();Document  document = reader.read(new File("input.xml"));</p>

2.解析XML形式的文本,得到document对象.

<p>String text = "<members></members>";Documentdocument = DocumentHelper.parseText(text);</p>

3.主动创建document对象.

<p>Document document = DocumentHelper.createDocument();//创建根节点</p><p>Element root = document.addElement("members");</p>

           ii.  第二步:修改XML文档的信息

1. 增:文档、标签、属性

//1.创建文档Document doc = DocumentHelper.createDocument();//2.增加标签Element rootElem = doc.addElement("contactList");//doc.addElement("contactList");Element contactElem = rootElem.addElement("contact");contactElem.addElement("name");//3.增加属性contactElem.addAttribute("id", "001");contactElem.addAttribute("name", "eric");

2.删:标签、属性

 1.删除标签     1.1得到标签对象  1.2删除标签对象

Element ageElem = doc.getRootElement().element("contact").element("age");//1.2 删除标签对象<span style="white-space:pre"></span>ageElem.detach();//先取得父标签,然后通过父标签移出自己//ageElem.getParent().remove(ageElem);

2.删除属性   2.1得到属性对象  2.2删除属性

//2.1得到属性对象//得到第二个contact标签Element contactElem = (Element)doc.getRootElement().elements().get(1);//2.2 得到属性对象Attribute idAttr = contactElem.attribute("id");//2.3 删除属性idAttr.detach();//idAttr.getParent().remove(idAttr);

3. 改:属性值、文本

方案一:修改属性值   1.得到标签对象 2.得到属性对象 3.修改属性值

//1.1  得到标签对象Element contactElem = doc.getRootElement().element("contact");//1.2 得到属性对象Attribute idAttr = contactElem.attribute("id");//1.3 修改属性值idAttr.setValue("003");

方案二:修改属性值1.1 得到标签对象1.2通过增加同名属性的方法,修改属性值

//1.1  得到标签对象Element contactElem = doc.getRootElement().element("contact");//1.2 通过增加同名属性的方法,修改属性值contactElem.addAttribute("id", "004");

修改文本 1.得到标签对象 2.修改文本

Element nameElem = doc.getRootElement().element("contact").element("name");nameElem.setText("李四");

                      ii.第三步:将修改后的XML文档写入到文件

FileOutputStream out = new FileOutputStream("e:/contact.xml");//1.指定写出的格式//紧凑的格式.去除空格换行.项目上线的时候OutputFormat format = OutputFormat.createCompactFormat();//漂亮的格式.有空格和换行.开发调试的时候//OutputFormat format = OutputFormat.createPrettyPrint();<pre name="code" class="java">/**
* 2.指定生成的xml文档的编码
*   同时影响了xml文档保存时的编码  和  xml文档声明的encoding的编码(xml解析时的编码)
*   结论: 使用该方法生成的xml文档避免中文乱码问题。
*/
format.setEncoding("utf-8");
//1.创建写出对象
XMLWriter writer = new XMLWriter(out,format);
//2.写出对象
writer.write(doc);
//3.关闭流
writer.close();

c)XPath技术:主要是用于快速获取所需的节点对象

1)导入xPath支持jar包。  jaxen-1.1-beta-6.jar

2)使用xpath方法

         List<Node>  selectNodes("xpath表达式");      查询多个节点对象

          Node       selectSingleNode("xpath表达式");  查询一个节点对象

                   3)xPath语法:

                           /       绝对路径      表示从xml的根位置开始或子元素(一个层次结构)

                            //      相对路径      表示不分任何层次结构的选择元素。

                            *       通配符        表示匹配所有元素

                            []      条件          表示选择什么条件下的元素

                            @      属性         表示选择属性节点

                            and     关系         表示条件的与关系(等价于&&)

                            text()    文本         表示选择文本内容

二、SAX解析:加载一点,读取一点,处理一点。对内存要求比较低。

<span style="white-space:pre"></span>   //创建sax解析器                   SAXParser sax =SAXParserFactory.newInstance().newSAXParser() ;                   //获取内容读取器                   XMLReader xml =  sax.getXMLReader() ;                   //注册一个内容处理器                   xml.setContentHandler(newDefaultHandler(){                            String curName ="" ;  //记录当前是那个标签                            int index = 0 ;  //记录读取到了那个作者                             public voidstartElement(String uri, String localName,                                               StringqName, Attributes attributes) throws SAXException {                                      if(qName.equals("作者")){                                               curName= "作者" ;                                               index++ ;                                     }                            }                             public voidendElement(String uri, String localName, String qName)                                               throwsSAXException {                                     curName ="" ;                            }                             public voidcharacters(char[] ch, int start, int length)                                               throwsSAXException {                                                                         if("作者".equals(curName)&& index == 2){                                               //说明读取到了第二本书的作者                                               System.out.println(newString(ch,start,length));                                     }                            }                   }) ;                   //加载xml文档                   xml.parse("src/book.xml");

============DOM解析    vs  SAX解析              ========

DOM解析

SAX解析

原理: 一次性加载xml文档,不适合大容量的文件读取

原理: 加载一点,读取一点,处理一点。适合大容量文件的读取

DOM解析可以任意进行增删改成

SAX解析只能读取

DOM解析任意读取任何位置的数据,甚至往回读

SAX解析只能从上往下,按顺序读取,不能往回读

DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。

SAX解析基于事件的编程方法。java开发编码相对复杂。






0 0
原创粉丝点击