Jaxp :Dom解析Xml文档和SAX解析Xml文档学习笔记

本文查阅方法:
    1、查阅目录 —— 查阅本文目录,确定想要查阅的目录标题
    2、快捷“查找” —— 在当前浏览器页面,按键 “Ctrl+F” 按键组合,开启浏览器的查找功能,
             在查找搜索框中 输入需要查阅的 目录标题,便可以直接到达 标题内容 的位置。
    3、学习小结 —— 文中的学习小结内容,是笔者在学习之后总结出的,开发时可直接参考其进行应用开发的内容, 进一步加快了本文的查阅 速度。(水平有限,仅供参考。)
 


 

 

 

本文目录 

 

  学习小结

 

  1、JAXP概述

 

  2、获得JAXP中的DOM解析器 

 

  3、使用DOM解析Xml文档 

 

  4、写回数据/更新XML文档

 

  5、DOM编程中的几个名词术语

 

  6、DOM方式解析XML文件——流程范例Demo

         A.DOM解析——获得Dom解析器:
         B.更新/写回数据到原Xml文档。(共三个步骤)
         C.遍历所有节点
         D.查找某一个节点
         E.向xml文档中添加新节点
         F.读取指定标签属性的值:
         G.向xml文档中指定位置上添加新节点
         H.向xml文档中指定节点添加属性
         I.删除xml文档中的指定节点
         J.删除2: 删除指定节点所在的父结点
         K.更新指定节点的文本内容

 

  7、Jaxp的SAX解析方式概述

 

  8、SAX解析原理剖析

 

  9、JDK文档中对Sax解析方式的描述(图解)

 

  10、SAX方式解析XML文档的流程

         (1)使用SAX解析Xml文档
         (2)样例Demo1:编写处理器——获取整个xml文档内容的处理器
         (3)样例Demo2:编写处理器—— 获取到指定位置序列标签的值 以及属性值
         (4)样例Demo3:编写处理器——  把Xml文档的数据封装到JavaBean的处理器

 

  11、编写SAX处理器的流程与注意事项:

 

  12、SAX 方式解析XML文件——流程范例Demo

 

 

 相关文章
    XML文档语法 学习笔记
        地址:http://even2012.iteye.com/blog/1828064

    DTD约束 —— Xml文档 约束技术 学习笔记
        地址:http://even2012.iteye.com/blog/1828290

    Schama —— Xml文档约束技术 学习笔记
        地址:http://even2012.iteye.com/blog/1832073

    Dom4j 解析Xml文档及 XPath查询  学习笔记
        地址:http://even2012.iteye.com/blog/1832068

    Jaxp :Dom解析Xml文档和SAX解析Xml文档学习笔记
        地址:http://even2012.iteye.com/blog/1829981


 

 

 

学习小结

 

(1)Jaxp —— Dom 解析Xml文档流程[共三个大步骤]

 

    A. 解析XML文档:            

 

         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    //得到工厂。

 

         DocumentBuilder builder = factory.newDocumentBuilder();                //得到Dom解析器。

 

         Document document = builder.parse("src/book.xml");                    //得到Dom文档。

 

    B. Dom编程:对Dom树中的Node、Element、Text、Attr等元素进行增、删、改、查的操作

 

                a. 获得目标节点:Node node=document.getElementsByTagName.item(0); 

 

                b. 应用该节点进行各种CRUD的操作。

 

                【备注:重点是先获取超级父类Node节点,进行操作,找不到合适的操作方法时,

 

                        可将其强转成其他对应的子节点,应用子类中更多的、有针对性的方法进行操作。】

 

    C. 更新/写回 XMl文档:

 

            TransformerFactory factory = TransformerFactory.newInstance();       //得到工厂。   

 

            Transformer tf = factory.newTransformer();                        //得到转换器。 

 

            tf.transform(new DOMSource(document),       //实例对象document是原来解析获得Dom对象。

 

                     new StreamResult(new FileOutputStream("src/book.xml")));   //输出到目标文件。

 

 

 

(2)Jaxp —— SAX解析Xml文档流程。[共两个大步骤]

 

    A. 使用SAX解析Xml文档    

 

            SAXParserFactory factory = SAXParserFactory.newInstance();   //1.创建产生解析器的工厂     

 

            SAXParser parser = factory.newSAXParser();                   //2.创建解析器     

 

            XMLReader reader = parser.getXMLReader();                    //3.得到xml文档读取器     

 

            reader.setContentHandler(new BookNameHandler());             //4.为读取器设置内容处理器     

 

            reader.parse("src/book.xml");                                //5.利用读取器解析xml文档       

 

    B. 编写处理器——实现所需要的功能。

 

            a. 新建类,并继承DefaultHandler 类

 

            b. 覆盖startElement(...)、characters(...)、endElement(...) 这三个方法,并在里面编写代码实现功能。

 

 

 


 

 

 

 

 

1、JAXP概述

 

    JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成

 

    在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX 的解析器对象。

 

    【小知识:改JVM虚拟内存(默认值:64m),防止Dom解析时造成内存溢出】

 

            命令行: java -Xmx566m

 

            MyEclipse--》VM参数:-Xmx566m

 


 

 

 

2、获得JAXP中的DOM解析器 

 

    javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对 象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance()静态方法 ,这 个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

 


 

 

 

3、使用DOM解析Xml文档

 

    a. 调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。 

 

    b. 调用工厂对象的 newDocumentBuilder()方法得到 DOM 解析器对象。 

 

    c. 调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,进而可以利用DOM特性对整个XML文档进行操作了。

 

    本例Demo见:标题“ 7、DOM方式解析XML文件” 中的范例

 

 

 


 

 

 

4、写回数据/更新XML文档

 

    javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,

 

        例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。

 

    (1)Transformer类通过transform(...)方法完成转换操作,该方法接收一个源和一个目的地。

 

    (2)源document:javax.xml.transform.dom.DOMSource类来关联要转换的document对象, 

 

    (3)目的地文件:用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。

 

    (4)Transformer对象通过TransformerFactory获得。

 

    本例Demo见:标题“ 7、DOM方式解析XML文件” 中的范例

 

 

 


 

  

 

5、DOM编程中的几个名词术语

 

    (1)DOM模型(document object model)

 

    (2)节点类型(Node对象)

 

        a.​DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。 

 

        b.Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象,如:Element,Attr,Text等),以便于调用其特有的方法。(查看API文档) 

 

        c.Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。

 

    (3)在dom中,节点之间关系如下:

 

        A. parent ———— 位于一个节点之上的节点是该节点的父节点(parent)

 

        B. children ——— 一个节点之下的节点是该节点的子节点(children) 

 

        C. sibling  ——— 同一层次,具有相同父节点的节点是兄弟节点(sibling[ˈsɪblɪŋ]) 

 

        D. descendant —— 一个节点的下一个层次的节点集合是节点后代(descendant[diˈsendənt] )

 

        E. ancestor ——— 父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor[ˈænsistə] ) 

 

   

 

 

 


 

 

 

 

 

6、DOM方式解析XML文件——流程范例Demo

 

    A.DOM解析——获得Dom解析器:

 

      Demo:        

 

        //得到dom解析器(共三个步骤)

 

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    //得到工厂。

 

            DocumentBuilder builder = factory.newDocumentBuilder();                //得到Dom解析器。

 

            Document document = builder.parse("src/book.xml");                    //得到Dom文档。

 

 

 

    B.更新/写回数据到原Xml文档。(共三个步骤) 

 

        Demo:

 

        //把内存中更新后对象树,重新定回到xml文档中

 

            TransformerFactory factory = TransformerFactory.newInstance();       //得到工厂。   

 

            Transformer tf = factory.newTransformer();                        //得到转换器。 

 

            tf.transform(new DOMSource(document),       //实例对象document是原来解析获得Dom对象。

 

                     new StreamResult(new FileOutputStream("src/book.xml")));   //输出到目标文件。

 

                                

 

    C.遍历所有节点

 

      Demo:

 

          @Test

 

          public void listXml() throws ParserConfigurationException, SAXException, Exception{

 

                list(document);

 

          }         

 

          public void list(Node node){    

 

                System.out.println(node.getNodeName());

 

                NodeList list = node.getChildNodes();

 

                for(int i=0;i<list.getLength();i++){

 

                      Node child = list.item(i);

 

                      list(child);

 

                }

 

          }

 

        

 

   D.查找某一个节点 

 

      Demo:

 

        //读取书名节点的值:<书名>javaweb开发</书名>

 

          @Test

 

          public void test1(){

 

            //得到dom解析器: 略... 

 

            Node node = document.getElementsByTagName("书名").item(0);

 

            String value = node.getTextContent();

 

            System.out.println(value);

 

          }

 

 

 

    E. 向xml文档中添加新节 

 

      Demo:        

 

          @Test

 

          public void test3() throws Exception{

 

            //得到dom解析器: 略...

 

            //创建要挂的节点

 

            Element price = document.createElement("售价");

 

            price.setTextContent("59元");

 

            //把创建的结点挂到书节点下

 

            Node book = document.getElementsByTagName("书").item(0);

 

            book.appendChild(price);

 

         

 

            //把内存中更新后对象树,重新定回到xml文档中:略。。。

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));

 

          }

 

 

 

     F.读取指定标签属性的值::

 

        Demo:     

 

          @Test  //<售价 type="rmb">39.00元</售价>

 

          public void test2(){

 

            //得到dom解析器: 略... 

 

            Node node = document.getElementsByTagName("售价").item(0);

 

            Element price =  (Element) node;   //发现node满足不了,把node强转成相应类型

 

            String attValue = price.getAttribute("type");

 

            System.out.println(attValue);

 

          }

 

  

 

    G.向xml文档中指定位置上添加新节点

 

      Demo:

 

          @Test

 

          public void test4() throws Exception{

 

            //得到dom解析器: 略...  

 

            //创建要添加的节点

 

            Element price = document.createElement("售价");

 

            price.setTextContent("59元"); 

 

            //得到要向哪个节点上挂子节点

 

            Node book = document.getElementsByTagName("书").item(0); 

 

            //向参考节点前,挂新节点

 

            book.insertBefore(price, document.getElementsByTagName("售价").item(0)); 

 

            //把内存中更新后对象树,重新定回到xml文档中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));         

 

          }

 

 

 

    H.向xml文档中指定节点添加属性

 

      Demo:

 

          @Test

 

          public void test5() throws Exception{

 

            //得到dom解析器: 略...   

 

            //得到要添加属性的节点

 

            Element author = (Element) document.getElementsByTagName("作者").item(0);

 

            author.setAttribute("id", "12");  //向节点挂属性 

 

            //把内存中更新后对象树,重新定回到xml文档中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));             

 

          }

 

  

 

    I.删除xml文档中的指定节点

 

      Demo:

 

          @Test

 

          public void test6() throws Exception{ 

 

            //得到dom解析器: 略...   

 

            //得到要删除的节点

 

            Node price = document.getElementsByTagName("售价").item(0);

 

            //得到要删除的节点的父亲

 

            Node parent = document.getElementsByTagName("书").item(0); 

 

            parent.removeChild(price); 

 

            //把内存中更新后对象树,重新定回到xml文档中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document),

 

                     new StreamResult(new FileOutputStream("src/book.xml")));

 

          }

 

 

 

    J.删除2: 删除指定节点所在的父结点

 

      Demo:

 

          @Test

 

          public void test7() throws Exception{ 

 

            //得到dom解析器: 略...   

 

            //得到要删除的节点

 

            Node price = document.getElementsByTagName("售价").item(0);

 

            price.getParentNode().getParentNode().removeChild(price.getParentNode()); 

 

            //把内存中更新后对象树,重新定回到xml文档中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));

 

          }

 

 

 

    K.更新指定节点的文本内容:

 

      Demo:

 

          @Test

 

          public void test8() throws Exception{

 

            //得到dom解析器: 略...  

 

            document.getElementsByTagName("售价").item(1).setTextContent("19元");

 

            //把内存中更新后对象树,重新定回到xml文档中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));

 

          } 

 

 

 

    G.附 book.xml 文件内容:

 

        <?xml version="1.0" encoding="UTF-8"?><书架>
         <书>
          <书名>javaweb开发</书名>
          <作者 id="12">张孝祥</作者>
          <售价>59元</售价>
          <售价 type="rmb">19元</售价> 
         </书> 
         <书>
          <书名>JavaScript网页开发</书名>
          <作者>张孝祥</作者>
          <售价>28.00元</售价>
         </书>
        </书架>

 

 

 


 

 

 

 

 

7、Jaxp的SAX解析方式概述

 

    DOM 解析的缺点—— 在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM 树的Doucment对象,从而再对XML文档进行 操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。     

 

    SAX解析的特点—— SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。

 


 

 

 

8、SAX解析原理剖析

 

    SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:

 

    (1)解析器——可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。解析器采用SAX方式在解 析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml 文件内容作为方法的参数传递给事件处理器。

 

    (2)事件处理器——由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

 


 

 

 

9、JDK文档中对Sax解析方式的描述(图解)

 

    备注:阅读ContentHandler API文档,常用方法:startElement、endElement、characters

 


             
 


 

 

10、SAX方式解析XML文档的流程

 

    (1)使用SAXParserFactory创建SAX解析工厂

 

        SAXParserFactory spf = SAXParserFactory.newInstance();

 

    (2) 通过SAX解析工厂得到解析器对象    

 

        SAXParser sp = spf.newSAXParser();

 

    (3) 通过解析器对象得到一个XML的读取器

 

        XMLReader xmlReader = sp.getXMLReader();

 

    (4) 设置读取器的事件处理器

 

        xmlReader.setContentHandler(new BookParserHandler());    //实现不同的功能,需要设置可提供相应功能的处理。 

 

    (5) 解析xml文件  

 

        xmlReader.parse("book.xml");

 


 

 

 

11、编写SAX处理器的流程与注意事项:

 

    (1)编写一个作为处理器的类:实现接口ContentHandler  或者 继承该接口的实现类:DefaultHandler

 

    (2)方式一:实现接口ContentHandler 

 

        实现该接口中所有的方法,常用的方法是:startElement()、endElement()、characters(). 

 

        缺点:需要在类中实现其全部方法(包括不需要使用的方法),是类中代码显得很乱。

 

    (3)方式二:继承该接口的实现类:DefaultHandler 

 

        仅需要覆盖 编程需要使用的方法,其他方法可以不覆盖。

 

        优点:类中仅仅包含所需要的方法,显得代码简洁,易于阅读维护。

 

              覆盖常用的方法是:startElement()、endElement()、characters().  

 

    (4)根据编程需要,在覆盖的方法中编写相应的程序代码。

 

        本例实现代码见下一标题:“13、SAX 方式解析XML文件——流程范例Demo”。

 


 

 

 

12、SAX 方式解析XML文件——流程范例Demo

 

    (1)使用SAX解析Xml文档    

 

        SAXParserFactory factory = SAXParserFactory.newInstance();   //1.创建产生解析器的工厂     

 

        SAXParser parser = factory.newSAXParser();                   //2.创建解析器     

 

        XMLReader reader = parser.getXMLReader();                    //3.得到xml文档读取器     

 

        reader.setContentHandler(new BookNameHandler());             //4.为读取器设置内容处理器     

 

        reader.parse("src/book.xml");                                //5.利用读取器解析xml文档 

 

  

 

    (2)样例Demo1:编写处理器——获取整个xml文档内容的处理器

 

        class ListHandler extends DefaultHandler{    //创建类,并继承

 

              public void startElement(String uri, String localName, String name,

 

                  Attributes atts) throws SAXException {

 

                        System.out.println("<" + name + ">");

 

              }

 

              public void endElement(String uri, String localName, String name) 

 

                  throws SAXException {

 

                        System.out.println("</" + name + ">");

 

              }

 

              public void characters(char[] ch, int start, int length)

 

                  throws SAXException {

 

                        System.out.println(new String(ch,start,length));

 

              }

 

        }

 

 

 

    (3)样例Demo2:编写处理器—— 获取到指定位置序列《书名》标签的值 以及属性值

 

        class BookNameHandler extends DefaultHandler{ 

 

              private String currentTag;

 

              private int count;  //记住当前解析到了几个书名标签

 

              @Override

 

              public void startElement(String uri, String localName, String name,

 

                  Attributes attributes) throws SAXException {

 

                    currentTag = name;

 

                    if("书名".equals(currentTag)){

 

                          count++;

 

                    }

 

                  //得到标签所有属性

 

                  for(int i=0;attributes!=null && i<attributes.getLength();i++){  //nullP

 

                       String attName = attributes.getQName(i);

 

                       String attValue = attributes.getValue(i);

 

                       System.out.println(attName + "=" + attValue);

 

                  }

 

              }             

 

              @Override

 

              public void characters(char[] ch, int start, int length)

 

                  throws SAXException {

 

                    if("书名".equals(currentTag) && count==1){    //指定位置序列 1

 

                          System.out.println(new String(ch,start,length));    //将得到的标签名及其属性值打印。

 

                    }

 

              }             

 

              @Override

 

              public void endElement(String uri, String localName, String name)

 

                  throws SAXException {

 

                    super.endElement(uri, localName, name);

 

              }

 

        }    

 

 

 

    (4)样例Demo3:编写处理器——  把书的数据封装到javabean的处理器

 

        class BeanListHandler extends DefaultHandler{ 

 

              private List list = new ArrayList();

 

              private Book book;    //自定义JavaBean类

 

              private String currentTag;

 

              public List getBooks(){

 

                    return list;

 

              }

 

         

 

              @Override

 

              public void startElement(String uri, String localName, String name,

 

                  Attributes attributes) throws SAXException {

 

                currentTag = name;

 

                if(name.equals("书")){

 

                  book = new Book();  //book.set

 

                }

 

              }

 

         

 

              @Override

 

              public void characters(char[] ch, int start, int length)

 

                  throws SAXException {

 

                    if(currentTag!=null && currentTag.equals("书名")){

 

                          book.setBookname(new String(ch,start,length));

 

                    }

 

                    if(currentTag!=null && currentTag.equals("作者")){

 

                          book.setAuthor(new String(ch,start,length));

 

                    }

 

                    if(currentTag!=null && currentTag.equals("售价")){

 

                          book.setPrice(new String(ch,start,length));

 

                    }

 

              }

 

         

 

              @Override

 

              public void endElement(String uri, String localName, String name)

 

                  throws SAXException {

 

                    if(name.equals("书")){

 

                          list.add(book);

 

                    }

 

                    currentTag = null;

 

              } 

 

        }

 

        附1:Domain类:Book.java

 

            public class Book {

 

                  private String bookname;

 

                  private String author;

 

                  private String price;

 

                  public String getBookname() {

 

                        return bookname;

 

                  }

 

                  public void setBookname(String bookname) {

 

                        this.bookname = bookname;

 

                  }

 

                  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;

 

                  }  

 

            }

 

        附2:Xml文件:book.xml

 

            <?xml version="1.0" encoding="UTF-8"?> 

 

            <书架> 

 

              <书> 

 

                <书名 name="aaa">javaweb开发</书名>  

 

                <作者>张孝祥</作者>  

 

                <售价>39元</售价> 

 

              </书>  

 

              <书> 

 

                <书名>JavaScript网页开发</书名>  

 

                <作者>张xx</作者>  

 

                <售价>890元</售价> 

 

              </书> 

 

            </书架>

 

  

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值