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

解析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());
    }
  • XML.03-DOM和SAX解析的更多相关文章

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

      一.介绍 dom是w3c指定的一套规范标准,核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文 ...

    2. Java SE之XML<二>XML DOM与SAX解析

      [文档整理系列] Java SE之XML<二>XML DOM与SAX解析 XML编程:CRUD(Create Read Update Delete) XML解析的两种常见方式: DOM(D ...

    3. java基础71 XML解析中的【DOM和SAX解析工具】相关知识点(网页知识)

      本文知识点(目录):本文下面的“实例及附录”全是DOM解析的相关内容 1.xml解析的含义    2.XML的解析方式    3.xml的解析工具    4.XML的解析原理    5.实例    6 ...

    4. schema文件及XML文件的DOM和Sax解析

      schema文件 <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="htt ...

    5. JAXP进行DOM和SAX解析

      1.常用XML的解析方式:DOM和SAX 1)DOM思想:将整个XML加载内存中,形成文档对象,所以对XML操作都对内存中文档对象进行. 2)SAX思想:一边解析,一边处理,一边释放内存资源---不允 ...

    6. Java 中,DOM 和 SAX 解析器有什么不同?

      DOM 解析器将整个 XML 文档加载到内存来创建一棵 DOM 模型树,这样可以 更快的查找节点和修改 XML 结构,而 SAX 解析器是一个基于事件的解析器, 不会将整个 XML 文档加载到内存.由 ...

    7. 2.2 使用 JAXP 对XML文档进行SAX解析

      使用JAXP 对 XML文档进行 SAX解析: public class Demo1 { /** * 使用JAXP对XML文档进行SAX解析 * @throws Exception * @throws ...

    8. Dom,pull,Sax解析XML

      本篇随笔将详细讲解如何在Android当中解析服务器端传过来的XML数据,这里将会介绍解析xml数据格式的三种方式,分别是DOM.SAX以及PULL. 一.DOM解析XML 我们首先来看看DOM(Do ...

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

      引言 NOKIA 有句著名的广告语:"科技以人为本".不论什么技术都是为了满足人的生产生活须要而产生的.详细到小小的一个手机.里面蕴含的技术也是浩如烟海.是几千年来人类科技的结晶, ...

    10. javaweb学习总结十二(JAXP对XML文档进行SAX解析)

      一:JAXP使用SAX方式解析XML文件 1:dom解析与sax解析异同点 2:sax解析特点 二:代码案例 1:xml文件 <?xml version="1.0" enco ...

    随机推荐

    1. Nginx限速遇到的问题

      公司使用的是Nginx做文件服务器,最近服务器流量增大,老板提出要给每个客户端进行限速. 在Nginx中进行限速配置: http { limit_zone one $binary_remote_add ...

    2. Python xlrd、xlwt、xlutils修改Excel文件

      一.xlrd读取excel 这里介绍一个不错的包xlrs,可以工作在任何平台.这也就意味着你可以在Linux下读取Excel文件.首先,打开workbook:    import xlrdwb = x ...

    3. 动态linq to list排序

      public class QeurySort { public static IList<T> Sort<T>(IList<T> list,string sidx, ...

    4. 错误 1 error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. d:\users\vs2013\le

      #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>void main(){    int nu ...

    5. BFS与DFS

      DFS:使用栈保存未被检测的结点,结点按照深度优先的次序被访问并依次被压入栈中,并以相反的次序出栈进行新的检测. 类似于树的先根遍历深搜例子:走迷宫,你没有办法用分身术来站在每个走过的位置.不撞南山不 ...

    6. Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄(转)

      用我的方法来控制其他程序窗体上的窗口控件,必须先了解什么是 回调函数.我的理解是这样的: 回 调函数写出来不是自己的程序去调用的,反而是让其他的东西去调用,比如windows操作系统,比如其他的程序等 ...

    7. 【摘】Mysql备份还原数据库之mysqldump实例及参数详细说明

      原文http://www.cnblogs.com/xuejie/archive/2013/01/11/2856911.html   我们在运营项目的过程中肯定会遇到备份数据库,还原数据库的情况,我们一 ...

    8. 如何彻底卸载Oracle

      如何彻底卸载Oracle 因为Oracle在Windows下的卸载颇有一些麻烦,如果不能完全卸载有可能影响将来的再次安装!常规卸载方法是运行Oracle的自带的卸载程序,可遗憾的是我在卸载时总不能完全 ...

    9. java关于值传递和引用传递的有趣试验

      上代码: public class Demo { public static void main(String[] args) { test_1(); test_2(); } public stati ...

    10. 根据word模板(contract_templet.tld)生成并下载word合同及根据wordHTML模板(contract_templetHTML.tld)预览合同内容

      1.action String templete=ConstantsAppParams.CONTRACT_TEMPLET_DOC;//contract_templet.tldString temple ...