前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >技术经验|Java-Web基础之XML解析JAXP-DOM

技术经验|Java-Web基础之XML解析JAXP-DOM

原创
作者头像
六月暴雪飞梨花
修改2023-09-24 20:04:29
修改2023-09-24 20:04:29
26300
代码可运行
举报
运行总次数:0
代码可运行

1 XML介绍和解析方式

「XML解析介绍」

XML是标记型文档,js 使用 dom 解析标记型文档是根据 html 的层级结构,在内存中分配一个属性结构,把 html 的标签,属性和文本都封装成 document 对象、element 对象,属性对象、文本对象,node 节点对象。

「XML」解析技术

xml的解析技术:dom 和 sax。

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

SAX:Simple APl for XML。这种方式不是官方标准,属于开源社区 XML-DEV,几乎所有的 XML 解析器都支持它。

「XML-dom」

特点:封装在内存处理。

优点:方便实现增删改的操作。

缺点:如果文件过大,可导致内存溢出。

「XML-sax」

特点:事件驱动,从上到下,依次解析,边读取边解析。

优点:不会导致内存溢出。

缺点:不能实现增删改的操作。

2 XML解析器

解析 XML 技术(dom 和 sax),需要一个解析器。

  • JAXP(Java AOI for XML Processing):是 SUN 公司推出的解析标准实现。
  • Dom4J:是开源组织推出的解析开发包。(实际开发中常用)
  • JDom:是开源组织推出的解析开发包。

2.1 JAXP-DOM解析

解析的逻辑同Python中差不多,如果了解其中一种语言,其他语言基本上可以去看下。

在JDK中,可以在rt.jar包中找到解析方法。

「步骤」

1、创建 DOM 解析器的工厂,得到 DOM 解析器对象

2、解析 XML 文档,得到代表整个文档的 Document 对象,将其放在内存中

3、获取根元素集合

4、解析处理

2.2 创建实验xml

首先创建一个xml,这里创建一个persons.xml,文件内容如下:

代码语言:javascript
代码运行次数:0
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<persons>
	<person sid="001">
		<name>张小帅</name>
		<sex>男</sex>
		<age>18</age>
	</person>
	<person sid="002">
		<name>刘晓萌</name>
		<sex>女</sex>
		<age>21</age>
	</person>
	<person sid="003">
		<name>王老四</name>
		<sex>男</sex>
		<age>38</age>
	</person>
</persons>

2.3 解析技术DOM

创建DomParserXmlTest.java,内容如下。

代码语言:javascript
代码运行次数:0
运行
复制
package com.xxx.tooljdk.xml;

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 java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * <p> DomParserXmlTest </p>
 */
public class DomParserXmlTest {

    public static void main(String[] args) {
        String xmlPath = "./tool-jdk8/src/main/java/com/xxx/tooljdk/xml/persons.xml";
        try {
            // 1、创建 DOM 解析器的工厂,得到 DOM 解析器对象
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

            // 2、解析 XML 文档,得到代表整个文档的 Document 对象,将其放在内存中
            Document document = builder.parse(xmlPath);

            // 3、获取根元素 persons
            System.out.println("----------------------------------------------------------------------");
            Element root = document.getDocumentElement();
            System.out.println("根元素节点名称:" + root.getNodeName());
            System.out.println("根元素节点类型(是一个元素:Element = 1):" + root.getNodeType());
            System.out.println("----------------------------------------------------------------------");

            NodeList personNode = document.getElementsByTagName("person");
            System.out.println("person节点数量:" + personNode.getLength());
            Node personEle = personNode.item(1);
            System.out.println("person元素节点名称:" + personEle.getNodeName());
            System.out.println("person元素节点文本内容:" + personEle.getTextContent());
            System.out.println("person元素节点属性名称:" + personEle.getAttributes().item(0).getNodeName());
            System.out.println("person元素节点属性值:" + personEle.getAttributes().item(0).getNodeValue());
            System.out.println("person元素节点属性类型(是一个属性:Attr = 2):" + personEle.getAttributes().item(0).getNodeType());
            System.out.println("----------------------------------------------------------------------");

            NodeList names = document.getElementsByTagName("name");
            System.out.println("所有name元素标签内存地址:" + names);
            System.out.println("索引为1的name元素标签名称:" + names.item(1).getNodeName());
            System.out.println("索引为1的name元素标签的值:" + names.item(1).getTextContent());
            System.out.println("----------------------------------------------------------------------");

            // 4、解析
            NodeList list = root.getChildNodes();
            ArrayList<Map<String, Object>> arr = new ArrayList<>();
            for (int i = 0; i < list.getLength(); i++) {

                // 遍历所有person节点
                Node item = list.item(i);
                if (item.getNodeType() == Node.ELEMENT_NODE) {
                    Map<String, Object> map = new HashMap<>();
                    NamedNodeMap attributes = item.getAttributes();

                    // 遍历所有person属性
                    for (int j = 0; j < attributes.getLength(); j++) {
                        Node nodePerson = attributes.item(j);
                        map.put(nodePerson.getNodeName(), nodePerson.getNodeValue());
                    }

                    // 遍历所有person节点的内容
                    NodeList list2 = item.getChildNodes();
                    for (int j = 0; j < list2.getLength(); j++) {
                        Node item2 = list2.item(j);
                        if (item2.getNodeType() == Node.ELEMENT_NODE) {
                            Node node = item2.getFirstChild();
                            if (item2.getNodeName().equals("name")) {
                                map.put("name", node.getTextContent());
                            }
                            if (item2.getNodeName().equals("sex")) {
                                map.put("sex", node.getTextContent());
                            }
                            if (item2.getNodeName().equals("age")) {
                                map.put("age", Integer.parseInt(node.getTextContent()));
                            }
                        }
                    }
                    arr.add(map);
                }
            }
            arr.forEach(System.out::println);
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2.4 执行结果

执行上面代码获取的结果如下:

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

根元素节点名称:persons

根元素节点类型(是一个元素:Element = 1):1

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

person节点数量:3

person元素节点名称:person

person元素节点文本内容:

 刘晓萌

 女

 21

person元素节点属性名称:sid

person元素节点属性值:002

person元素节点属性类型(是一个属性:Attr = 2):2

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

所有name元素标签内存地址:com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl@27d6c5e0

索引为1的name元素标签名称:name

索引为1的name元素标签的值:刘晓萌

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

{sex=男, name=张小帅, age=18, sid=001}

{sex=女, name=刘晓萌, age=21, sid=002}

{sex=男, name=王老四, age=38, sid=003}

还有一些其他方法,例如:

获取第一个节点:getFirstChild()

获取最后一个节点:getLastChild()

其他的一些属性,建议参考下JDK的源代码来加深理解。

2.5 新增节点

「步骤」

1、创建position_level元素

2、创建position_level的文本

3、把文本添加到position_level

4、把 position_level 添加到 索引为1的 person 下面

5、回写 xml

代码语言:javascript
代码运行次数:0
运行
复制
// --------------------------------------------------------------------------
            // 5、为person新增一个标签:职级等级(position_level),他的内容是:三级
            // 创建position_level元素
            Element pLevel = document.createElement( "position_level" );
            // 创建position_level的文本
            Text pLevelText = document.createTextNode( "三级" );
            // 把文本添加到position_level
            pLevel.appendChild(pLevelText);
            // 把 position_level 添加到 索引为1的 person 下面
            personEle.appendChild(pLevel);
            // 回写 xml
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.transform(new DOMSource(document), new StreamResult(xmlPath));
            // --------------------------------------------------------------------------

执行完成代码之后,我们查看下原来的persons.xml,可以看到我们增加的标签position_level已经增加进来。

也可以看出来,我们新增的节点并没有美化展示到xml中,而且还给我们增加了一个属性standalone="no"。

2.6 修改节点

「步骤」

1、得到age元素

2、修改age值,设置到age元素上

3、回写xml,使之生效

代码语言:javascript
代码运行次数:0
运行
复制
            // --------------------------------------------------------------------------
            // 6、修改第一个人的年龄为28
            System.out.println("----------------------------------------------------------------------");
            // 得到age
            Node ageNode = document.getElementsByTagName("age").item(0);
            System.out.println("原始年龄:" + ageNode.getTextContent());
            // 修改age值
            ageNode.setTextContent("28");
            System.out.println("修改后的年龄:" + ageNode.getTextContent());
            // 回写xml
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.transform(new DOMSource(document), new StreamResult(xmlPath));
            // --------------------------------------------------------------------------

执行完成代码之后,我们查看下原来的persons.xml

代码语言:javascript
代码运行次数:0
运行
复制
原始年龄:18
修改后的年龄:28

可以看到我们增加的标签age已经增加进来。

2.7 删除节点

删除刚才的新增的position_level节点。

「步骤」

1、获取position_level节点元素

2、得到position_level父节点

3、使用父节点删除当前节点操作

4、回写xml,使之生效

代码语言:javascript
代码运行次数:0
运行
复制
          // 7、删除position_level节点
            System.out.println("----------------------------------------------------------------------");
            // 获取position_level节点元素
            Node pLevel = document.getElementsByTagName("position_level").item(0);
            // 得到position_level父节点
            Node pLevelParentNode = pLevel.getParentNode();
            // 使用父节点删除当前节点操作
            pLevelParentNode.removeChild(pLevel);
            // 回写xml
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.transform(new DOMSource(document), new StreamResult(xmlPath));

执行完成代码之后,我们查看下原来的persons.xml已经没有position_level这个节点元素了。

3 DOM技术

在DOM中,主要适用的是元素和节点以及属性。

针对元素有如下方法:

针对节点有如下方法:

DocumentBuilder API

DocumentBuilderFactory API

👏👏👏

好了,今天的分享就到了这里,下次再见!!!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 XML介绍和解析方式
  • 2 XML解析器
    • 2.1 JAXP-DOM解析
    • 2.2 创建实验xml
    • 2.3 解析技术DOM
    • 2.4 执行结果
    • 2.5 新增节点
    • 2.6 修改节点
    • 2.7 删除节点
  • 3 DOM技术
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档