当前位置: 首页 > 工具软件 > JAXP > 使用案例 >

JAXP解析XML文件之DOM解析

姜经武
2023-12-01

JAXP解析XML文件之DOM解析

常用的XML解析器

1) JAXP

2)  DOM4J

3)  JDOM

4)  Digester

什么是JAXP

JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成在javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX 的解析器对象。

JAXP核心API

DocumentBuilderFactory:是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。调用工厂对象的newDocumentBuilder方法得到 DOM 解析器对象(DocumentBuilder)。

DocumentBuilder:用于从XML文档中获取DOM文档实例。调用 DocumentBuilder的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,这样可以利用DOM特性对整个XML文档进行操作了。

Document代表了一个XML文档的树模型。以后所有的对XML文档的操作,都与解析器无关,直接在这个Document对象上进行操作就可以了。

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

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

Ø  位于一个节点之上的节点是该节点的父节点(parent)

Ø  一个节点之下的节点是该节点的子节点(children

Ø  同一层次,具有相同父节点的节点是兄弟节点(sibling

Ø  一个节点的下一个层次的节点集合是节点后代(descendant)

Ø  父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)

节点(Node)可以是元素节点(Element)、属性节点(Attr)、文本节点(Text)、实体节点(Entity)等等。Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。

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

Transformer:用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。

Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:

javax.xml.transform.dom.DOMSource类来关联要转换的document对象,

用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。

 Transformer对象通过TransformerFactory获得。

体验JAXP

Jaxp.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<department>
    <user no="001">
        <name>郭靖</name>
        <six>男</six>
        <age>25</age>
    </user>
    <user no="002">
        <name>黄蓉</name>
        <six>女</six>
        <age>20</age>
    </user>
</department>

解析代码

package com.rabbit.jaxp;

import org.junit.Test;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * jaxp解析dom树
 * Created by HASEE on 2018/5/3.
 */
public class JaxpDomDemo {

    @Test
    public void deleteElem() throws Exception {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //创建DocumentBuilder对象
        DocumentBuilder builder = factory.newDocumentBuilder();
        //通过DocumentBuilder解析XML文档,创建Document对象
        //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径
        Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath());
        //找到需要删除的节点
        Element elem = (Element)doc.getElementsByTagName("age").item(1);
        //利用父节点删除
        elem.getParentNode().removeChild(elem);
        //刷新内存的数据到磁盘
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer former = tFactory.newTransformer();
        former.transform(new DOMSource(doc),
                new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath())));
    }

    @Test
    public void updateAttr() throws Exception {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //创建DocumentBuilder对象
        DocumentBuilder builder = factory.newDocumentBuilder();
        //通过DocumentBuilder解析XML文档,创建Document对象
        //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径
        Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath());
        //获取要挂载的元素
        Element elem = (Element)doc.getElementsByTagName("user").item(0);
        elem.setAttribute("code", "100");
        //刷新内存的数据到磁盘
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer former = tFactory.newTransformer();
        former.transform(new DOMSource(doc),
                new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath())));
    }

    //动态创建元素并挂载
    @Test
    public void updateElem() throws Exception {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //创建DocumentBuilder对象
        DocumentBuilder builder = factory.newDocumentBuilder();
        //通过DocumentBuilder解析XML文档,创建Document对象
        //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径
        Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath());
        //获取要挂载的元素
        Element elem = (Element)doc.getElementsByTagName("age").item(0);
        elem.setTextContent("100");
        //刷新内存的数据到磁盘
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer former = tFactory.newTransformer();
        former.transform(new DOMSource(doc),
                new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath())));
    }

    @Test
    public void createAttr() throws Exception {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //创建DocumentBuilder对象
        DocumentBuilder builder = factory.newDocumentBuilder();
        //通过DocumentBuilder解析XML文档,创建Document对象
        //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径
        Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath());
        //获取要挂载的元素
        Element elem = (Element)doc.getElementsByTagName("user").item(0);
        elem.setAttribute("code", "001");
        //刷新内存的数据到磁盘
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer former = tFactory.newTransformer();
        former.transform(new DOMSource(doc),
                new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath())));
    }

    //动态创建元素并挂载
    @Test
    public void createElem() throws Exception {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //创建DocumentBuilder对象
        DocumentBuilder builder = factory.newDocumentBuilder();
        //通过DocumentBuilder解析XML文档,创建Document对象
        //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径
        Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath());
        //创建元素
        Element like = doc.createElement("like");
        like.setTextContent("游泳");
        //获取要挂载的元素
        Element elem = (Element)doc.getElementsByTagName("user").item(0);
        //挂载
        elem.appendChild(like);
        //刷新内存的数据到磁盘
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer former = tFactory.newTransformer();
        former.transform(new DOMSource(doc),
                new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath())));
    }

    //初步体验
    @Test
    public void test() throws ParserConfigurationException, IOException, SAXException {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //创建DocumentBuilder对象
        DocumentBuilder builder = factory.newDocumentBuilder();
        //通过DocumentBuilder解析XML文档,创建Document对象
        Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath());
        //获取XML文档的根节点
        Node root = doc.getChildNodes().item(0);
        parseChildNode(root);
    }

    private void parseChildNode(Node root) {
        //打印节点名称
        System.out.println(root.getNodeName());
        NodeList cList = root.getChildNodes();
        for(int i=0;i<cList.getLength();i++){
            Node cNode = cList.item(i);
            parseChildNode(cNode);
        }

    }

}
 类似资料: