XML.03-DOM和SAX解析

body,td { font-family: calibri; font-size: 10pt }

  • XML.03-DOM和SAX解析

      • XML的DOM解析

        • 解析
        • 处理
        • 回写
      • XML的SAX解析
        • SAX和DOM方式的不同:
        • SAX解析原理
        • SAX解析范例

解析xml常用的有两种方式,DMO和SAX

DOM和SAX的区别:

  • DOM:

    • 在内存中生成树桩结构
    • 优点是可以支持增删改查各种操作
    • 缺点在于,如果文档过大的时候,可能会产生内存溢出的风险
  • SAX:
    • 基于事件驱动,边读边解析
    • 优点:占用内存小
    • 缺点,不支持增删改操作.(DOM4J会在内存中生成树状结构,虽然是SAX方式解析…)

XML的DOM解析

xml的DOM解析,主要会用到两个包中的类

  • javax.xml.parsers :用来解析
  • javax.xml.transform:用来回写

解析

    public static Document getDocument(String src) throws Exception{        //获取工厂类        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();        //获取解析器        DocumentBuilder builder = factory.newDocumentBuilder();        //返回Document(org.w3c.dom.Document)        return builder.parse(src);    }

处理

在拿到document之后,就可以想干哈就干哈了.

在元素末尾增加一个子元素

    /**     * DOM大法之--在元素末尾增加一个元素     * @throws Exception      */    public static void addElementTest() throws Exception{        //解析        Document document = JaxpDomUtils.getDocument("src/book.xml");        //处理        NodeList nodeList = document.getElementsByTagName("书");        Node book2 = nodeList.item(1);

Element cat = document.createElement("cat");        cat.setTextContent("I am a cat");        book2.appendChild(cat);        //回写        JaxpDomUtils.writeBack(document, "src/book.xml");    }

这个地方需要注意,Node和Element. Node表示文档树上的一个节点,这个文档不局限于HTML或者XML,而element表示HTML或者xml中一个元素.

在任意位置增加元素

    /**     * DOM大法之--在任意位置增加元素     * @throws Exception     */    public static void addElementAnyWhereTest() throws Exception{        Document document = JaxpDomUtils.getDocument("src/book.xml");        Node book2  = document.getElementsByTagName("书").item(1);        Node author2 = document.getElementsByTagName("作者").item(1);        Element cat = document.createElement("cat");        cat.setTextContent("I am a cat too");        book2.insertBefore(cat, author2);        JaxpDomUtils.writeBack(document, "src/book.xml");    }

删除一个节点

    /**     * DOM大法之--删除一个元素     * @throws Exception     */    public static void deleteNodeTest() throws Exception{        Document document = JaxpDomUtils.getDocument("src/book.xml");        Node cat1 = document.getElementsByTagName("cat").item(0);        Node book = cat1.getParentNode();        book.removeChild(cat1);        JaxpDomUtils.writeBack(document, "src/book.xml");

}

这里比较蛋疼的是,必须先找到要删除的元素,然后再找他爹,然后通过他爹的remove方法把它删掉…

    /**     * DOM大法之--修改元素     * @throws Exception     */    public static void  changeNodeTest() throws Exception {        Document document = JaxpDomUtils.getDocument("src/book.xml");        Node author2 = document.getElementsByTagName("作者").item(1);        author2.setTextContent("西川结衣");        JaxpDomUtils.writeBack(document, "src/book.xml");

}

查找

    /**     * DOM大法之--删除一个元素     * @throws Exception     */    public static void deleteNodeTest() throws Exception{        Document document = JaxpDomUtils.getDocument("src/book.xml");        Node cat1 = document.getElementsByTagName("cat").item(0);        Node book = cat1.getParentNode();        book.removeChild(cat1);        JaxpDomUtils.writeBack(document, "src/book.xml");

}

Node下面有很多get方法,需要的时候再翻文档吧.

回写

    public static void writeBack(Document document, String dest) throws Exception{        //回写的工厂类        TransformerFactory factory = TransformerFactory.newInstance();        Transformer transformer = factory.newTransformer();        transformer.transform(new DOMSource(document), new StreamResult(dest));    }

XML的SAX解析

SAX和DOM方式的不同:

  • DOM需要将整个XML文件都读取后再进行解析,如果XML文档非常大,就会消耗计算机的大量内存,并且容易导致内存溢出
  • SAX 是边读边解析.

SAX解析原理

SAX方式和DOM方式的套路差不多. 只有一点不一样,SAX方式没有增删改的功能,只是单纯的读取解析,所以就没有回写的必要了.
这玩意儿主要的方法,大概是这个样子的:
void parse(String uri, DefaultHandler dh)

那么这里就涉及到两个东西:

  • 解析器:

    • 获取解析器工厂
    • 获取解析器对象
    • 解析XML(XML 文件路径,事件处理器)

    解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

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

  • 事件处理器:
    • 一般用DefaultHandler,他是SAX时间处理程序的默认基类.
    • 基于事件触发,比如遇到一个开始标签,就会去执行startElement()方法…(消息订阅机制?! 貌似上学的时候学过这玩意儿…)
      对于一个标准的XML它的消息触发机制大概是这个样子的.

    SAX解析范例

    写一个自己的Handler

    /** * 解析xml文件 * @author thecatcher * */class MyHandler1 extends DefaultHandler{
    
    //开始标签    @Override    public void startElement(String uri, String localName, String qName,            Attributes attributes) throws SAXException {        System.out.println("read a start label for an element:"+qName);    }    //元素内容    @Override    public void characters(char[] ch, int start, int length)            throws SAXException {        String str = new String(ch,start,length);        System.out.println(str);    }    //结束标签    @Override    public void endElement(String uri, String localName, String qName)            throws SAXException {        System.out.println("read a end label for an element:"+qName);    }}

    发散一下,既然是个方法那就可以自己定义行为了. 比如读取特定标签

    /** * 读取特定标签 * @author thecatcher * */class MyHandler21 extends DefaultHandler{    private boolean flag=false;    private int count =0;    @Override    public void startElement(String uri, String localName, String qName,            Attributes attributes) throws SAXException {        if("作者".equals(qName)){            flag=true;            count++;        }    }
    
    @Override    public void characters(char[] ch, int start, int length)            throws SAXException {        if(flag&&count==2){            String str=new String(ch, start, length);            System.out.println(str);
    
    }    }    @Override    public void endElement(String uri, String localName, String qName)            throws SAXException {        flag=false;    }}

    解析主类:

        public void readXMLTest() throws ParserConfigurationException, SAXException, IOException{        SAXParserFactory factory = SAXParserFactory.newInstance();        SAXParser parser = factory.newSAXParser();        parser.parse("src/book2.xml", new MyHandler21());    }
  • 时间: 2024-10-07 09:39:44

    XML.03-DOM和SAX解析的相关文章

    iOS开发中XML的DOM和SAX解析方法

    一.介绍 dom是w3c指定的一套规范标准,核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文件.xml文件很大时,建立的“树”也会大,所以会大量占用内存. sax解析器核心是事件处理机制.例如解析器发现一个标记的开始标记时,将所发现的数据会封装为一个标记开始事件,并把这个报告给事件处理器,事件处理器再调用方法(startElement)处理发现的数据.下面我们尝试一下SAX和DOM解析:

    2018/1/1 XML和DOM、SAX解析

    1.XML (1)描述带关系的数据(软件的配置文件) (2)数据的载体(小型的"数据库")2.语法:标签: 标签名不能以数字开头,中间不能有空格,区分大小写.有且仅有一个根标签.属性: 可有多个属性,但属性值必须用引号(单引号或双引号)包含,但不能省略,也不能单双混用.文档声明: <?xml version="1.0" encoding="utf-8"?> encoding="utf-8": 打开或解析xml文档时

    XML学习笔记(二):使用 DOM和SAX 解析XML :

    一.XML解析的简介 1.一般来说xml解析的方式有两种,Dom与SAX,且各有优缺点.pull是第三种方法见:pull解析XML 1)DOM:dom对象树 ①.整个XML放入内存,转换为Document对象: ②.每个元素,转换成Element对象 ③.文本,转换成Text对象 ④.属性,转换成Attribute对象 优缺点:元素的CRUD比较简单,但是内存消耗大,大的xml文档不适合. 补充:内存不足时,可以修改参数,调整JVM的内存大小 1.java.lang.OutOfMemoryErr

    Java SE之XML&lt;二&gt;XML DOM与SAX解析

    [文档整理系列] Java SE之XML<二>XML DOM与SAX解析 XML编程:CRUD(Create Read Update Delete) XML解析的两种常见方式: DOM(Document Object Model): 特点:树状解析 优点:[更适合对XML文档的(crud)操作.]对XML文档增删改查操作很方便灵活 缺点:内存消耗很大,不适合数据量很大,节点很多的XML文档. SAX(Simple API for XML): 特点:自上往下顺序解析 优点:[占用内存小,解析速度

    Java学习之Xml系列五:SAX解析——搜索xml内容

    本文对SAX解析进一步说明. 另外主要给利用SAX解析方法找到指定条件(如标签名称)的xml文档内容. 首先按需要介绍一下DefaultHandler. DefaultHandler类是SAX2事件处理程序的默认基类.它继承了EntityResolver.DTDHandler.ContentHandler和ErrorHandler这四个接口.包含这四个接口的所有方法,所以我们在编写事件处理程序时,可以不用直接实现这四个接口,而继承该类,然后重写我们需要的方法.(注意:ContentHandler

    DOM和SAX解析XML的区别

    解析xml有四种方法:DOM,SAX,DOM4j,JDOM.     我们主要学了两种:DOM和SAX.     DOM适于解析比较简单的XML而SAX则适于解析较复杂的XML文件.各有各的好. DOM和SAX的不同:     1. DOM是基于内存的,不管文件有多大,都会将所有的内容预先装载到内存中.从而消耗很大的内存空间.而SAX是基于事件的.当某个事件被触发时,才获取相应的XML的部分数据,从而不管XML文件有多大,都只占用了少量的内存空间.     2. DOM可以读取XML也可以向XM

    XML学习总结-DOM和SAX解析-综合案例-(四)

    ============DOM解析    vs   SAX解析             ======== DOM解析 SAX解析 原理: 一次性加载xml文档,不适合大容量的文件读取 原理: 加载一点,读取一点,处理一点.适合大容量文件的读取 DOM解析可以任意进行增删改成 SAX解析只能读取 DOM解析任意读取任何位置的数据,甚至往回读 SAX解析只能从上往下,按顺序读取,不能往回读 DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单. S

    XML - 十分钟了解XML结构以及DOM和SAX解析方式

    引言 NOKIA 有句著名的广告语:"科技以人为本".不论什么技术都是为了满足人的生产生活须要而产生的.详细到小小的一个手机.里面蕴含的技术也是浩如烟海.是几千年来人类科技的结晶,单个人穷其一生也未必能掌握其一角.只是个人一直觉得主要的技术和思想是放之四海而皆准的,很多技术未必须要我们从头到尾再研究一遍.我们要做的就是站在巨人的肩膀上.利用其成果来为人们的需求服务. 随着移动互联网时代的大潮.越来越多的App不光是须要和网络server进行数据传输和交互,也须要和其它 App 进行数据

    XML解析之DOM ,SAX解析区别

    环境配置:导入GDataXMLNode.h 文件 1.导入GDataXMLNode.h 文件时,需要导入动态库 libxml2.2.tbd 动态库 , 2.再在Build setting下面找到 Header Search Paths ,插入 /usr/include/libxml2 3. 最后在Build Phases中的Compile Sources 下找到GDataXMLNode.m文件,在后面加上 -fno-objc-arc  因为这个三方是MRC环境的 SAX解析和DOM解析的区别:

    XML的DOM、SAX、DEMO4J及DEMO4J整合Path的代码例子

    1.DMO解析 package cn.itcast.xml.dom; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.No