XML解析---DOM方式

XML解析方法分为两种:DOM方式和SAX方式

DOM:Document Object Model,文档对象模型。这种方式是W3C推荐处理XML的一种方式

SAX:Simple API for XML。该方式不是官方标准,属于开源社区XML-DEV

XML解析开发包

JAXP:SUN公司推出的解析标准实现

Dom4J:开源组织推出的解析开发包

JDOM:同上

JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成

org.w3c.dom:提供DOM方方式解析XML的标准接口

org.xml.sax:提供SAX方式解析XML的标准接口

javax.xml:提供了解析XML文档的类

javax.xml.parsers包中,定义了几个工厂类。我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象。

DocumentBuilderFactory

SAXParersFactory

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

利用JAXP继续DOM解析

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance()方法

,这个方法会根据本地默认安装的解析器自动创建一个工厂对象并返回

DOM方式解析会读取完整个XML文档,在内存中构建代表整个DOM树的Document对象,从而再对XML文档进行操作:增、删、改、查

如果文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。

获得JAXP中的DOM解析器

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

--->调用工厂对象的newDocumentBuilder()方法得到DOM解析器对象

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

1 /*固定写法*/
2 //得到解析工厂DocumentBuilderFactory
3 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
4
5 //得到解析器
6 DocumentBuilder builder = factory.newDocumentBuilder();
7
8 //解析指定的XML文档
9 Document document = builder.parse("src/book.xml");

DOM模型(document object model)

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

在dom中,节点之间的关系如下:

  • 位于一个节点之上的节点是该节点的父节点(parent)
  • 一个节点之下的节点是该节点的子节点(children)
  • 在同一层次,具有相同父节点的节点是兄弟节点(sibling)
  • 一个节点的下一个层次的节点集合是节点后代(descendant)
  • 父、祖父节点以及所有位于节点的上面的,都是节点的祖先(ancestor)

节点的类型

  Node对象提供了一系列常量来代表节点的类型,当开发人员获得某个Node类型之后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便调用其特有的方法

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

如何更新XML文档

  • javax.xml.transform包中de Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出。例如把XML文件应用样式表后转成一个html文档。利用这个对象
  • 把Document对象又重新写入到XML文件中
    • Transformer通过transform方法完成转换的操作,该方法接收一个源和一个目的地
    • javax.xml.transform.dom.DOMSource类来关联要转换的Document对象
    • 用javax.xml.transform.strem.StreamResult对象来表示数据的目的地  
  • Transformer对象提供TransformerFactory获得 
  • 1 // 把内存中Documeng树写回XML文件中
    2         TransformerFactory facotry = TransformerFactory.newInstance();
    3          //创建factory实例
    4           Transformer ts = facotry.newTransformer();
    5          ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
    6           //将源写入到目的中去

     

  1 import javax.xml.parsers.DocumentBuilder;
  2 import javax.xml.parsers.DocumentBuilderFactory;
  3 import javax.xml.transform.Transformer;
  4 import javax.xml.transform.TransformerFactory;
  5 import javax.xml.transform.dom.DOMSource;
  6 import javax.xml.transform.stream.StreamResult;
  7
  8 import org.w3c.dom.Document;
  9 import org.w3c.dom.Element;
 10 import org.w3c.dom.Node;
 11 import org.w3c.dom.NodeList;
 12
 13 //利用Jaxp进行DOm方式解析
 14 public class JaxpDomDemo {
 15
 16     public static void main(String[] args) throws Exception {
 17         // 得到解析工厂DocumentBuilderFactory
 18         //得到解析工厂DocumentBuilderFacetory
 19         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 20         // 得到解析器DocumentBuilder
 21         DocumentBuilder builder = factory.newDocumentBuilder();
 22         // 解析指定的XML文档,得到代表内存DOM树的Document对象
 23         Document document = builder.parse("src/book.xml");
 24         test3(document);
 25     }
 26
 27     // 1、得到某个具体的节点内容:打印第2本书的作者
 28     public static void test1(Document document) {
 29         // 根据标签的名称获取所有的作者元素
 30         NodeList nl = document.getElementsByTagName("作者");                       //Nodelist getElementByTagName(Stirng tagname按文档顺序返回包含文档中且具有给定标记名称的所有Element的NodeList
 31         

            // 按照索引取第2个作者元素 NodeList 有两个主要的方法Node item(int index) 返回集合中的第index个项,如果index大于或等于此列表的索引则返回null       //int getLength()返回列表的节点数。有效子节点索引的范围是0到length-1
 32         Node node = nl.item(1);
 33         // 打印该元素的文本
 34         String text = node.getTextContent();   //node有许多操作方法 getTextContent()方法返回此节点及其后代的文本相关内容
 35         System.out.println(text);
 36     }
 37
 38     // 2、遍历所有元素节点:打印元素的名称
 39     public static void test2(Node node) {
 40         // 判断当前节点是不是一个元素节点
 41         if (node.getNodeType() == Node.ELEMENT_NODE) {
 42             // 如果是:打印他的名称
 43             System.out.println(node.getNodeName());
 44         }
 45         // 如果不是:找到他的孩子们
 46         NodeList nl = node.getChildNodes(); //NodeList getChildNodes()包含此节点的NodeList。如果不存在,这是不包含节点的NodeList
 47         int len = nl.getLength();
 48         for (int i = 0; i < len; i++) {
 49             // 遍历孩子们:递归
 50             Node n = nl.item(i);
 51             test2(n);
 52         }
 53     }
 54
 55     // 3、修改某个元素节点的主体内容:把第一本书的售价改为38.00元
 56     public static void test3(Document document) throws Exception {
 57         // 找到第一本书的售价
 58         NodeList nl = document.getElementsByTagName("售价");
 59         // 设置其主体内容
 60         Node node = nl.item(0);
 61         node.setTextContent("39.00元");
 62         // 把内存中Documeng树写回XML文件中
 63         TransformerFactory facotry = TransformerFactory.newInstance();
 64         //创建factory实例
 65         Transformer ts = facotry.newTransformer();
 66         ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
 67         //将源写入到目的中去
 68
 69     }
 70
 71     // 4、向指定元素节点中增加子元素节点:第一本中增加子元素<内部价>99.00</内部价>
 72     public static void test4(Document document) throws Exception {
 73         // 创建一个新的元素并设置其主体内容
 74         Element e = document.createElement("内部价");
 75         e.setTextContent("99.00元");
 76         // 找到第一本书元素
 77         Node firstBookNode = document.getElementsByTagName("书").item(0);
 78         // 把新节点挂接到第一本书上
 79         firstBookNode.appendChild(e);
 80         // 把内存中Documeng树写回XML文件中
 81         TransformerFactory facotry = TransformerFactory.newInstance();
 82         Transformer ts = facotry.newTransformer();
 83         ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
 84     }
 85
 86     // 5、向指定元素节点上增加同级元素节点:在第一本书的售价前面增加批发价
 87     public static void test5(Document document) throws Exception {
 88         // 创建一个新的元素并设置其中的主体内容
 89         Element e = document.createElement("批发价");
 90         e.setTextContent("58.00元");
 91         // 找到第一本书的售价
 92         Node firstPrice = document.getElementsByTagName("售价").item(0);
 93         // 在售价的前面加入新建的元素:增加子元素一定要使用父元素来做
 94         firstPrice.getParentNode().insertBefore(e, firstPrice); //增加子元素一定要使用父元素来做
 95         // 把内存中Documeng树写回XML文件中
 96         TransformerFactory facotry = TransformerFactory.newInstance();
 97         Transformer ts = facotry.newTransformer();
 98         ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
 99     }
100
101     // 6、删除指定元素节点:删除内部价
102     public static void test6(Document document) throws Exception {
103         // 找到内部价节点,用爸爸删除 删除的时候要有父节点删除子节点
104         Node n = document.getElementsByTagName("内部价").item(0);
105         n.getParentNode().removeChild(n);
106         // 把内存中Documeng树写回XML文件中
107         TransformerFactory facotry = TransformerFactory.newInstance();
108         Transformer ts = facotry.newTransformer();
109         ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
110     }
111
112     // 7、操作XML文件属性:打印第一本书的出版社
113     public static void test7(Document document) throws Exception {
114         // 得到第一本书
115         //document.getElementByTagName("书") 获取书说有元素
116         Node n = document.getElementsByTagName("书").item(0); //item(0)获取第一个元素
117         // 打印指定属性的取值
118         Element e = (Element) n; //打印指定的属性值
119         System.out.println(e.getAttribute("出版社")); //getAttribute()
120     }
121
122     // 8、添加一个出版社属性给第二本书
123     public static void test8(Document document) throws Exception {
124         // 得到第二本书
125         Node n = document.getElementsByTagName("书").item(1);
126         // 打印指定属性的取值
127         Element e = (Element) n;
128         e.setAttribute("出版社", "上海传智"); //设置该值
129         // 把内存中Documeng树写回XML文件中
130         //把内存中的Document树写回到XML文件中
131         TransformerFactory facotry = TransformerFactory.newInstance();
132         Transformer ts = facotry.newTransformer();
133         ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
134     }
135 }

测试

 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 2 <exam>
 3     <student examid="222" idcard="111">
 4         <name>张三</name>
 5         <location>沈阳</location>
 6         <grade>89</grade>
 7     </student>
 8     <student examid="444" idcard="333">
 9         <name>李四</name>
10         <location>大连</location>
11         <grade>97</grade>
12     </student>
13     <student examid="666" idcard="555">
14         <name>李宗瑞</name>
15         <location>台北</location>
16         <grade>100.0</grade>
17     </student>
18 </exam>

建立一个学生类

 1 public class Student {
 2     private String idcard;
 3     private String examid;
 4     private String name;
 5     private String location;
 6     private float grade;
 7     public String getIdcard() {
 8         return idcard;
 9     }
10     public void setIdcard(String idcard) {
11         this.idcard = idcard;
12     }
13     public String getExamid() {
14         return examid;
15     }
16     public void setExamid(String examid) {
17         this.examid = examid;
18     }
19     public String getName() {
20         return name;
21     }
22     public void setName(String name) {
23         this.name = name;
24     }
25     public String getLocation() {
26         return location;
27     }
28     public void setLocation(String location) {
29         this.location = location;
30     }
31     public float getGrade() {
32         return grade;
33     }
34     public void setGrade(float grade) {
35         this.grade = grade;
36     }
37     @Override
38     public String toString() {
39         return "Student [examid=" + examid + ", grade=" + grade + ", idcard="
40                 + idcard + ", location=" + location + ", name=" + name + "]";
41     }
42
43 }

创建一个接口:该接口有以以下的功能

  • 添加学生信息到XML中
  • 根据准考证号查询学生信息 如何学生不在,则返回null
  • 根据学生姓名删除学生
package com.meijunjie.dao;
import com.meijunjie.domain.Student;
public interface IStudentDao {

    /**
     * 添加学生信息到XML中
     * @param s
     * @return
     */
    boolean createStudent(Student s);

    /**
     * 根据准考证号查询学生信息
     * @param examid
     * @return 如果学生不存在,返回null
     */
    Student findStudent(String examid);

    /**
     * 根据学生姓名删除学生
     * @param name
     * @return 如果人不存在也返回false
     */
    boolean deleteStudent(String name);

}

创建工具类采用DOM方式解析XML文档 ,更新XML文档

 1 package cn.meijunjie.util;
 2
 3 import javax.xml.parsers.DocumentBuilder;
 4 import javax.xml.parsers.DocumentBuilderFactory;
 5 import javax.xml.transform.Transformer;
 6 import javax.xml.transform.TransformerFactory;
 7 import javax.xml.transform.dom.DOMSource;
 8 import javax.xml.transform.stream.StreamResult;
 9
10 import org.w3c.dom.Document;
11 //操作XML的工具类
12 //工具类中的异常可以抛也可以处理
13 public class DocumentUtil {
14     public static Document getDocument() throws Exception{       //读取XML文档
15         DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
16         return builder.parse("src/exam.xml");
17     }       //向XML文档中写入
18     public static void write2xml(Document document)throws Exception{
19         Transformer ts = TransformerFactory.newInstance().newTransformer();
20         ts.transform(new DOMSource(document), new StreamResult("src/exam.xml"));
21     }
22 }

实现该接口

package cn.meijunjie.dao;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cn.itcast.domain.Student;
import cn.itcast.util.DocumentUtil;
//异常:抛的话,上层能解决才行
//上一层如果处理不了,自己必须处理。

public class StudentDao implements IStudentDao {
    /**
     * 添加学生信息到XML中
     * @param s
     * @return
     */
    public boolean createStudent(Student s){
        System.out.println("JAXP");
        //目标:在根元素exam中添加student子元素
        boolean result = false;
        try {
            Document document = DocumentUtil.getDocument(); //读取文档内容
            //创建name、location、grade元素并设置其主体内容
            Element nameE = document.createElement("name");
            nameE.setTextContent(s.getName());
            Element locationE = document.createElement("location");
            locationE.setTextContent(s.getLocation());
            Element gradeE = document.createElement("grade");
            gradeE.setTextContent(s.getGrade()+"");
            //创建student元素,并设置其属性
            Element studentE = document.createElement("student");
            studentE.setAttribute("idcard", s.getIdcard());
            studentE.setAttribute("examid", s.getExamid());//CTRL+ALT+ARROW

            studentE.appendChild(nameE);
            studentE.appendChild(locationE);
            studentE.appendChild(gradeE);
            //得到exam元素,把student挂接上去
            Node node = document.getElementsByTagName("exam").item(0);
            node.appendChild(studentE);
            //写回XML文件中
            DocumentUtil.write2xml(document);
            result = true;
        } catch (Exception e) {
            throw new RuntimeException(e);//异常转义。异常链
        }
        return result;
    }
    /**
     * 根据准考证号查询学生信息
     * @param examid
     * @return 如果学生不存在,返回null
     */
    public Student findStudent(String examid){
        Student s = null;

        try{
            //得到Document对象
            Document document = DocumentUtil.getDocument();
            //得到所有的student元素
            NodeList nl = document.getElementsByTagName("student");
            //遍历student元素,判断他的examid属性的取值是否与参数匹配
            for(int i=0;i<nl.getLength();i++){
                Node node = nl.item(i);
//                if(node.getNodeType()==Node.ELEMENT_NODE){
//                    Element e = (Element)node;
                if(node instanceof Element){
                    Element e = (Element)node;
                    if(e.getAttribute("examid").equals(examid)){
                    //如果匹配:说明找到了学生;创建学生对象
                        s = new Student();
                    //设置学生对象的各个属性取值
                        s.setExamid(examid);
                        s.setIdcard(e.getAttribute("idcard"));
                        s.setName(e.getElementsByTagName("name").item(0).getTextContent());
                        s.setLocation(e.getElementsByTagName("location").item(0).getTextContent());
                        s.setGrade(Float.parseFloat(e.getElementsByTagName("grade").item(0).getTextContent()));
                    }
                }
            }
        }catch(Exception e){
            throw new RuntimeException(e);
        }

        return s;
    }
    /**
     * 根据学生姓名删除学生
     * @param name
     * @return 如果人不存在也返回false
     */
    public boolean deleteStudent(String name){
        boolean result = false;
        try{
            //得到Document对象
            Document document = DocumentUtil.getDocument();
            //得到所有的name元素
            NodeList nl = document.getElementsByTagName("name");
            //遍历name元素,判断其主体内容是否与参数一致
            for(int i=0;i<nl.getLength();i++){
                //如果一致:找到他的爸爸的爸爸,删除它的爸爸
                Node n = nl.item(i);
                if(n.getTextContent().equals(name)){
                    n.getParentNode().getParentNode().removeChild(n.getParentNode());
                    //写回XML文档
                    DocumentUtil.write2xml(document);
                    result = true;
                    break;
                }
            }
        }catch(Exception e){
            throw new RuntimeException(e);
        }
        return result;
    }
}
时间: 2024-08-25 13:30:54

XML解析---DOM方式的相关文章

JAVA解析XML之DOM方式

JAVA解析XML之DOM方式 准备工作 创建DocumentBuilderFactory对象;    创建DocumentBuilder对象; 通过DocumentBuilder对象的parse方法加载xml 解析XML文件的属性名和属性值 解析XML文件的节点名和节点值 常用方法如下: getElementsByTagName(); getLength(); item(); getNodeName(); getNodeValue(); getNodeType(); *getAttribute

Android中XML解析-Dom解析

Android中需要解析服务器端传过来的数据,由于XML是与平台无关的特性,被广泛运用于数据通信中,有的时候需要解析xml数据,格式有三种方式,分别是DOM.SAX以及PULL三种方式,本文就简单以Dom解析为例,解析XML, DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的,但是这样一来,如果xml文件很大,手机CPU处理能力比PC差,因此在处理效率方面就相对差了,使用Dom解析就不是太合适了. 基础维护 首先下assets目录下新建一个Bo

Android] Android XML解析学习——方式比较

[Android] Android XML解析学习——方式比较 (ZT) 分类: 嵌入式 (From:http://blog.csdn.net/ichliebephone/article/details/5981913) 一.基础知识 经过这段时间的学习,我们已经了解了Android平台上用于解析XML的三种方式:SAX.DOM和Pull.并且在学习的过程中也介绍了这三种方式各自的特点及适合的使用场合,简单的来说,DOM方式最直观和容易理解,但是只适合XML文档较小的时候使用,而SAX方式更适合

XML引入,DOM 方式解析XML 原理,SAX 方式解析XML

XML 简介 Xml(eXtensible Markup Language) 即可扩展标记语言.提供了一套跨平台.跨网络.跨程序的语言的数据描述方式,使用XML 可以方便地实现数据交换.系统配置.内容管理等常见功能. 元素VS 节点 节点包括元素节点.属性节点.文本节点:元素一定是节点,但是节点不一定是元素: <?xml version="1.0" encoding="UTF-8"?> <emp> <empName empNo=&quo

006_03Java解析XML之DOM方式与SAX方式

XML解析方式分为两种:DOM方式和SAX方式 DOM:Document Object Model,文档对象模型.这种方式是W3C推荐的处理XML的一种方式. SAX:Simple API for XML.这种方式不是官方标准,属于开源社区XML-DEV,几乎所有的XML解析器都支持它. XML解析开发包 JAXP:是SUN公司推出的解析标准实现. Dom4J:是开源组织推出的解析开发包. JDom:是开源组织推出的解析开发包. JAXP: JAXP:(Java API for XML Proc

XML 解析---dom解析和sax解析

目前XML解析的方法主要用两种: 1.dom解析:(Document Object Model,即文档对象模型)是W3C组织推荐的解析XML的一种方式. 使用dom解析XML文档,该解析器会先把XML文档加载到内存中,生成该XML文档对应的document对象,然后把XML文档中的各个标签元素变成相应的Element对象,文本会变成Text对象,属性会变成Attribute对象,并按这些标签.文本.属性在XML文档中的关系保存这些对象的关系. 缺点:消耗内存,所以使用dom解析XML文档时不能解

XML解析 DOM(1)

DOM解析使用Google提供的一个开源高效的XML解析工具GDataXMLNode ,它的效率要比NSXMLParser 要快10倍      使用方式:     1.小导入系统动态链接库 libxml2.2.dylib     2.在buildSettings中的Header Search Path 中添加 /usr/include/libxml2     3.在buildSettings中的Other Linker Flags 中添加 -lxml2 获取解析文件路径 NSString *

XML通过dom方式插入html中时解决对多空格的处理。

如何显示空格? 通常情况下,HTML会自动截去多余的空格.不管你加多少空格,都被看做一个空格.比如你在两个字之间加了10个空格,HTML会截去9个空格,只保留一个.为了在网页中增加空格,你可以使用 表示空格. 如下有一段XML信息: <?xml version='1.0' encoding='gb2312'?><detail><row RowState='Unchanged' ID='6' Ts='0000000000a48042' ProductName='女NH相机包单反

XML数据解析 Dom方式解析

这是一份XML数据,与上一篇文章的JSON数据内容是相同的,上一篇是JSON格式,这篇文章使用的是XML格式的数据 本文以上篇文章的代码为基础修改: 1>数据形式变为XML数据,所以要修改文件的路径 2>因为数据格式不同,所以解析方式不同先采用GData方式解析XML文档 需求:将此XML文档中的数据解析出来,通过tableView展示出来,上一篇文章的需求相同,只是数据与解析方法不同 此处只给出解析本分代码,即JSON解析2文章中代码部分,61--89行部分,开始部分修改文件路径. 使用GD