使用DOM解析XML文档,及维护(新增、修改、删除操作)详尽步骤

DOM概念 :

文档对象模型。DOM把XML文件映射成一棵倒挂的“树”,以根元素为根节点,每个节点都以对象的形式存在

大体步骤:

1.借助字节输入流,获取当前xml文档到jvm虚拟机中(磁盘->jvm)

  InputStream is = new FileInputStream("src/com/tencent/test2/dom.xml");

2.使用DOM解析器解析xml文档
2.1.得到DOM工厂实例对象

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

2.2.从工厂中获取DOM解析工具

DocumentBuilder tool = factory.newDocumentBuilder();

2.3借助工具,将流中的xml字节文档转为doc
注:Document对象:代表整个xml文档,所有其他节点都以一定的顺序包含在其内部,我们总是会先得到这个对象,然后再执行后续操作

Document doc = tool.parse(is);

3.维护xml文档(新增、修改、删除操作)

4.重新保存到磁盘中(jvm->磁盘)
4.1.借助字节输出流,将doc存入流中

 OutputStream os=new FileOutputStream("src/com/tencent/test2/dom.xml");

4.2.得到工厂实例

TransformerFactory factory = TransformerFactory.newInstance();

4.3.从工厂中获取工具

 Transformer tool = factory.newTransformer();

4.4.开始传输,但是需要先准备数据源和目标位置
4.4.1.数据源:

DOMSource dom =new DOMSource(doc);

4.4.2.目标位置:

 StreamResult result=new StreamResult(os);

4.4.3.借助工具,将流中的dom输出到磁盘中

tool.transform(dom,result);

实现代码:

整体思路:
1.先创建一个dom.xml文档(相对路径)

<?xml version="1.0" encoding="UTF-8" standalone="no"?><students>

    <student>
        <name>张三</name>
        <age>19</age>
        <stuno>16001</stuno>
    </student>

    <student>
        <name>李四</name>
        <age>18</age>
        <stuno>16002</stuno>
    </student>

    <student>
        <name>王五</name>
        <age>21</age>
        <stuno>16003</stuno>
        <!--<atuno>16003</atuno>此位置字母不小心打错了!!还是应为  stuno  -->
    </student>

</students>

在这里插入图片描述

2.导入的包(不需要手动打)

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

3.创建一个DOM测试类

public class DomTest{
	Document doc;//将Document doc;定义在单个方法外,方便全局使用
}

4.开始

步骤1:借助字节输入流,获取当前xml文档到jvm虚拟机中(磁盘->jvm),并获得DOM解析器

@Before

    public void init() throws Exception {

        //1.借助字节输入流从磁盘获取xml文档到流中
        InputStream is = new FileInputStream("src/com/tencent/test2/dom.xml");

        //2.通过DOM工具从流中获取到JVM虚拟机中

        //2.1.得到DOM工厂实例对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        //2.2.从工厂中获取DOM解析工具
        DocumentBuilder tool = factory.newDocumentBuilder();

        //2.3借助工具,将流中的xml字节文档转为doc
        doc = tool.parse(is);
    }

步骤2:解析

    @Test

    public void demo1() {
        //3.解析

//      Element root = doc.getDocumentElement();//获取根结点

        NodeList studentList = doc.getElementsByTagName("student");//直接获取指定节点“student”的所有集合列表,即所有的student

        for (int i = 0; i < studentList.getLength(); i++) {//循环遍历展示

            Node oneStudent = studentList.item(i);//挨个获取这个集合列表中的节点元素,即每个student

            if (oneStudent.getNodeType() == Node.ELEMENT_NODE) {//如果取出来的这个student是节点的话,就继续

                NodeList oneStudentList = oneStudent.getChildNodes();//取出每个student节点的子节点组成一个集合列表,即单个student下的所有子节点

                for (int j = 0; j < oneStudentList.getLength(); j++) {//循环取出这个集合列表

                    Node oneStudentChild = oneStudentList.item(j);//挨个获取这个集合列表中的节点元素,即每个student的子节点

                    if (oneStudentChild.getNodeType() == Node.ELEMENT_NODE) {//如果取出来的这个是节点的话,就继续

                        String textName = oneStudentChild.getTextContent();//获取这个节点的值

                        String nodeName = oneStudentChild.getNodeName();//获取这个节点的名字

                        System.out.println(nodeName + "---" + textName);

                    }
                }
            }
        }

        System.out.println("已完成解析!!!");
        
    }

demo1运行效果图:
在这里插入图片描述

步骤3:维护

新增

@Test

    public void demo2(){

        //4.1.新增

        //添加要新增的标签
        Element studentElement = doc.createElement("student");

        Element nameElement = doc.createElement("name");

        Element ageElement = doc.createElement("age");

        Element stunoElement = doc.createElement("stuno");

        //添加要新增标签的值
        Text nameText = doc.createTextNode("麻子");

        Text ageText = doc.createTextNode("22");

        Text stunoText = doc.createTextNode("16004");

        //建立父子关系
            //建立标签与标签之间的关系,即name,age,stuno标签属于studnet
        studentElement.appendChild(nameElement);

        studentElement.appendChild(ageElement);

        studentElement.appendChild(stunoElement);

            //建立标签与标签的值之间的关系,即name,age,stuno标签与他们的值一一对应
        nameElement.appendChild(nameText);

        ageElement.appendChild(ageText);

        stunoElement.appendChild(stunoText);

            //建立子标签与根标签之间的关系,即student属于students根标签
        doc.getDocumentElement().appendChild(studentElement);

        System.out.println("已完成新增!!!");
    }

demo2运行效果图:
在这里插入图片描述
在这里插入图片描述
修改

@Test

    public void demo3(){

        //4.2.修改(与解析步骤一致)

        NodeList studentList = doc.getElementsByTagName("student");

        for (int i = 0; i < studentList.getLength(); i++) {

            Node oneStudent = studentList.item(i);

            if (oneStudent.getNodeType()==Node.ELEMENT_NODE){

                NodeList oneStudentList = oneStudent.getChildNodes();

                for (int j = 0; j < oneStudentList.getLength(); j++) {

                    Node oneStudentChild = oneStudentList.item(j);

                    if (oneStudentChild.getNodeType()==Node.ELEMENT_NODE){

                        String nodeName = oneStudentChild.getNodeName();

                        String textName = oneStudentChild.getTextContent();

                        if (nodeName.equals("name")&&textName.equals("麻子")){//如果找到子节点的名字是name且子标签的值是“麻子”时

                           oneStudentChild.setTextContent("春丽");//就将该节点的值改为“春丽”

                            System.out.println("已完成修改!!!");

                           break;
                        }
                    }
                }
            }
        }
    }

demo3运行效果图:
在这里插入图片描述
在这里插入图片描述
删除

@Test

    public void demo4(){

        //4.3.删除(与解析步骤一致),原则:父删除子

        NodeList studentList = doc.getElementsByTagName("student");

        for (int i = 0; i < studentList.getLength(); i++) {

            Node oneStudent = studentList.item(i);

            if (oneStudent.getNodeType()==Node.ELEMENT_NODE){

                NodeList oneStudentList = oneStudent.getChildNodes();

                for (int j = 0; j < oneStudentList.getLength(); j++) {

                    Node oneStudentChild = oneStudentList.item(j);

                    if (oneStudentChild.getNodeType()==Node.ELEMENT_NODE){

                        String nodeName = oneStudentChild.getNodeName();

                        String textName = oneStudentChild.getTextContent();

                        if (nodeName.equals("name")&&textName.equals("春丽")){//如果找到子节点的名字是name且子标签的值是“春丽”时

                            //我们在这演示删除根节点students下符合条件的student节点

                            Node parentNode = oneStudentChild.getParentNode().getParentNode();//寻找该节点的父节点,再寻找此时节点的父节点,即寻找该节点的父节点的父节点(根节点)

                            parentNode.removeChild(oneStudentChild.getParentNode());//然后删除此节点下的子节点

                            System.out.println("已完成删除!!!");

                            break;
                        }
                    }
                }
            }
        }
    }

demo4运行效果图:
在这里插入图片描述
在这里插入图片描述

步骤4:借助字节输出流,重新保存到磁盘中(jvm->磁盘)

@After

    public void end() throws Exception {

        //借助字节输出流,将doc存入流中
        OutputStream os=new FileOutputStream("src/com/tencent/test2/dom.xml");

        //得到工厂实例
        TransformerFactory factory = TransformerFactory.newInstance();

        //从工厂中获取工具
        Transformer tool = factory.newTransformer();

        //开始传输,但是需要先准备数据源和目标位置
            //数据源:
        DOMSource dom =new DOMSource(doc);
            //目标位置
        StreamResult result=new StreamResult(os);

        //借助工具,将流中的dom输出到磁盘中
        tool.transform(dom,result);
    }

整体代码:

package com.tencent.test2;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

public class DomTest {

    Document doc;


    @Before

    public void init() throws Exception {

        //1.借助字节输入流从磁盘获取xml文档到流中
        InputStream is = new FileInputStream("src/com/tencent/test2/dom.xml");

        //2.通过DOM工具从流中获取到JVM虚拟机中

        //2.1.得到DOM工厂实例对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        //2.2.从工厂中获取DOM解析工具
        DocumentBuilder tool = factory.newDocumentBuilder();

        //2.3借助工具,将流中的xml字节文档转为doc
        doc = tool.parse(is);


    }


    @Test

    public void demo1() {
        //3.解析

//      Element root = doc.getDocumentElement();//获取根结点

        NodeList studentList = doc.getElementsByTagName("student");//直接获取指定节点“student”的所有集合列表,即所有的student

        for (int i = 0; i < studentList.getLength(); i++) {//循环遍历展示

            Node oneStudent = studentList.item(i);//挨个获取这个集合列表中的节点元素,即每个student

            if (oneStudent.getNodeType() == Node.ELEMENT_NODE) {//如果取出来的这个student是节点的话,就继续

                NodeList oneStudentList = oneStudent.getChildNodes();//取出每个student节点的子节点组成一个集合列表,即单个student下的所有子节点

                for (int j = 0; j < oneStudentList.getLength(); j++) {//循环取出这个集合列表

                    Node oneStudentChild = oneStudentList.item(j);//挨个获取这个集合列表中的节点元素,即每个student的子节点

                    if (oneStudentChild.getNodeType() == Node.ELEMENT_NODE) {//如果取出来的这个是节点的话,就继续

                        String textName = oneStudentChild.getTextContent();//获取这个节点的值

                        String nodeName = oneStudentChild.getNodeName();//获取这个节点的名字

                        System.out.println(nodeName + "---" + textName);

                    }
                }
            }
        }

        System.out.println("已完成解析!!!");

    }


    @Test

    //4.维护

    public void demo2(){

        //4.1.新增

        //添加要新增的标签
        Element studentElement = doc.createElement("student");

        Element nameElement = doc.createElement("name");

        Element ageElement = doc.createElement("age");

        Element stunoElement = doc.createElement("stuno");

        //添加要新增标签的值
        Text nameText = doc.createTextNode("麻子");

        Text ageText = doc.createTextNode("22");

        Text stunoText = doc.createTextNode("16004");

        //建立父子关系
            //建立标签与标签之间的关系,即name,age,stuno标签属于studnet
        studentElement.appendChild(nameElement);

        studentElement.appendChild(ageElement);

        studentElement.appendChild(stunoElement);

            //建立标签与标签的值之间的关系,即name,age,stuno标签与他们的值一一对应
        nameElement.appendChild(nameText);

        ageElement.appendChild(ageText);

        stunoElement.appendChild(stunoText);

            //建立子标签与根标签之间的关系,即student属于students根标签
        doc.getDocumentElement().appendChild(studentElement);

        System.out.println("已完成新增!!!");
    }


    @Test

    public void demo3(){

        //4.2.修改(与解析步骤一致)

        NodeList studentList = doc.getElementsByTagName("student");

        for (int i = 0; i < studentList.getLength(); i++) {

            Node oneStudent = studentList.item(i);

            if (oneStudent.getNodeType()==Node.ELEMENT_NODE){

                NodeList oneStudentList = oneStudent.getChildNodes();

                for (int j = 0; j < oneStudentList.getLength(); j++) {

                    Node oneStudentChild = oneStudentList.item(j);

                    if (oneStudentChild.getNodeType()==Node.ELEMENT_NODE){

                        String nodeName = oneStudentChild.getNodeName();

                        String textName = oneStudentChild.getTextContent();

                        if (nodeName.equals("name")&&textName.equals("麻子")){//如果找到子节点的名字是name且子标签的值是“麻子”时

                           oneStudentChild.setTextContent("春丽");//就将该节点的值改为“春丽”

                            System.out.println("已完成修改!!!");

                           break;
                        }
                    }
                }
            }
        }
    }


    @Test

    public void demo4(){

        //4.3.删除(与解析步骤一致),原则:父删除子

        NodeList studentList = doc.getElementsByTagName("student");

        for (int i = 0; i < studentList.getLength(); i++) {

            Node oneStudent = studentList.item(i);

            if (oneStudent.getNodeType()==Node.ELEMENT_NODE){

                NodeList oneStudentList = oneStudent.getChildNodes();

                for (int j = 0; j < oneStudentList.getLength(); j++) {

                    Node oneStudentChild = oneStudentList.item(j);

                    if (oneStudentChild.getNodeType()==Node.ELEMENT_NODE){

                        String nodeName = oneStudentChild.getNodeName();

                        String textName = oneStudentChild.getTextContent();

                        if (nodeName.equals("name")&&textName.equals("春丽")){//如果找到子节点的名字是name且子标签的值是“春丽”时

                            //我们在这演示删除根节点students下符合条件的student节点

                            Node parentNode = oneStudentChild.getParentNode().getParentNode();//寻找该节点的父节点,再寻找此时节点的父节点,即寻找该节点的父节点的父节点(根节点)

                            parentNode.removeChild(oneStudentChild.getParentNode());//然后删除此节点下的子节点

                            System.out.println("已完成删除!!!");

                            break;
                        }
                    }
                }
            }
        }
    }


    @After

    public void end() throws Exception {

        //借助字节输出流,将doc存入流中
        OutputStream os=new FileOutputStream("src/com/tencent/test2/dom.xml");

        //得到工厂实例
        TransformerFactory factory = TransformerFactory.newInstance();

        //从工厂中获取工具
        Transformer tool = factory.newTransformer();

        //开始传输,但是需要先准备数据源和目标位置
            //数据源:
        DOMSource dom =new DOMSource(doc);
            //目标位置
        StreamResult result=new StreamResult(os);

        //借助工具,将流中的dom输出到磁盘中
        tool.transform(dom,result);
    }
}






发布了15 篇原创文章 · 获赞 11 · 访问量 958

猜你喜欢

转载自blog.csdn.net/qq_41414186/article/details/100581372