Java对XML文档的解析

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

Java对XML文档的解析的相关文章

java操作xml文档

目前最常用的XML解析技术是DOM和SAX. DOM是基于XML的树结构来完成解析的,适用于多次访问的XML文档,但是DOM解析比较消耗资源:而SAX是基于事件解析,适用于大数据量的XML文档,占用资源少,内存消耗小. DOM是文档对象模型(Document Object Model) 首先DOM会将XML文档映射成一颗倒挂的树,在这棵树中,每个节点都是以节点对象的形式存在的. 我们通过操作这些对象就可以完成XML文件的读写任务了. 我们可以直接根据节点的名称或属性查找该节点对象,也可以根据一个

XML文档的解析

XML文档解析:操作xml文档,将文档中的数据读取到内存中  * 操作xml文档   1. 解析(读取):将文档中的数据读取到内存中   2. 写入:将内存中的数据保存到xml文档中.持久化的存储 * 解析xml的方式:   1. DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树    * 优点:操作方便,可以对文档进行CRUD的所有操作    * 缺点:占内存   2. SAX:逐行读取,基于事件驱动的.    * 优点:不占内存.    * 缺点:只能读取,不能增删改 * x

XPath对XML文档的解析

首先,得感谢一下写XPath的开发人员考虑到中国人编写了中文文档! 使用XPath让我们解析XML文档变得更加灵活简单了. package it.xiehe.xml; import java.io.File; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Node; import org.dom4j.io.SAXReader; /* *

java将XML文档转换成json格式数据

功能 将xml文档转换成json格式数据 说明 依赖包: 1. jdom-2.0.2.jar : xml解析工具包; 2. fastjson-1.1.36.jar : 阿里巴巴研发的高性能json工具包 程序源码 package com.xxx.open.pay.util; import com.alibaba.fastjson.JSONObject; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdo

关于XML文档pull解析的新思考-内省的应用

今天,复习黑马第6天学习的pull解析XML文档,结合第10天讲的JavaBean,突然了有了新的思考. 以下是我创建的XML文档: <?xml version="1.0" encoding="UTF-8"?> <!-- 定义一个演示文档,存储黑马的所有班级,以及每个班级的信息 利用XML的功能之一:XML用来表示生活中有关系的数据  -->  <itheima>   <class>   <name>Anr

javaweb学习总结十三(dom4j方式对XML文档进行解析)

一:dom4j方式介绍 对于xml的解析总共有三种 1:jaxp方式,是sun公司开发的,分为sax方式和dom方式 2:jdom方式,后来其中部分人员参与开发dom4j 3:dom4j方式,是现在企业使用比较多的一种方式 二:代码案例 1:读取xml文件中某个节点 1):获取第二个学生的名字 1 @Test 2 // 1:获取第二个学生的名字 3 public void test01() throws DocumentException { 4 // 1:获取解析器 5 SAXReader r

浅谈用java解析xml文档(三)

接上一篇,本文介绍使用JDOM解析xml文档, 首先我们还是应该知道JDOM从何而来,是Breet Mclaughlin和Jason Hunter两大Java高手的创作成果,2000年初, JDOM作为一个开放源代码项目正式开始研发.JDOM是一种解析XML的Java工具包. JDOM基于树状结构,利用纯JAVA技术对XML文档实现解析.生成.序列化及其它操作. 我们从以下步骤开始解析: (1).通过JDOM的API创建一个SAXBuilder的对象 SAXBuilder saxBuilder

浅谈用java解析xml文档(一)

关于xml本身的语法及使用的环境不多说了,网上有很多规则, 然对xml文档进行解析,一般分为四种解析方式,基于java官方文档的Dom 和Sax解析,还有就是基于 第三方jar包的 Jdom 和 Dom4j解析. 一.首先我们来看Dom解析: 1.定义工厂,使应用程序能够从 XML 文档获取生成 DOM 对象树的解析器. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 在应用程序获取对 DocumentBuil

Java学习总结(21)——XML文档解析:DOM解析,SAX解析

一.XML简介1.可扩展性标记语言(eXtensible Markup Language)2.XML用于描述数据3.应用场合:(1)持久化存储数据(2)数据交换(3)数据配置4.XML语法(1)文档类型:在编写XML文档时,需要先使用文档声明,声明XML文档的类型.最简单的声明语法:<?Xml version="1.0" ?>用encoding属性说明文档的字符编码:<?Xml version="1.0" encoding="GB2312