Java中XML解析的方式介绍和实现

在日常开发中常见的XML解析方式有如下两种

1.DOM:

        要求解析器将整个XML文件全部加载到内存中,生成一个Document对象

                1.优点:元素和元素之间保留结构、关系,可以针对元素进行增删查改操作

                2.缺点:如果XML文件过大,可能会导致内存溢出

2.SAX:

        是一种速度更快,更加高效的解析方式。它是逐行扫描,边扫描边解析,并且以事件驱动的方式来进行具体的解析,每解析一行都会触发一个事件

                1.优点:不会出现内存溢出的问题,可以处理大文件

                2.缺点:只能读,不能写

        解析器就是根据不同的解析方式提供具体的实现,为了方便开发人员来解析XML,有一些方便操作的类库。

dom4j:比较简单的XML解析的类库

Jsoup:功能强大的DOM方式解析的类库,尤其对HTML的解析更加方便

本人的项目结构,一点要注意XML路径!!

Java中XML解析的方式介绍和实现_第1张图片

使用dom4j解析user.xml

  1. 创建解析器对象
  2. 使用解析器对象读取XML文档生成Document对象
  3. 根据Document对象获取xML的元素(标签)信息

Dom4j重要的APl说明

        org.dom4j.Document常用方法

Element getRootElement();//获取xML文件的根节点

        org.dom4j.Element的常用方法

String getName(); //返回标签的名称
List elements(); //获取标签的子标签

String attributeValue(String name);//获取指定属性名称的属性值

String getText();//获取标签的文本

String elementText(Stringname);//获取措定名称的子标签的文本

完整代码

package com.itheima.demo.dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

/**
 * dom4j解析用户xml测试
 *
 * @author YZH
 * @date 2023/12/20
 */
public class Dom4jParseUserXmlTest {
    public static void main(String[] args) {
        // 创建解析器对象
        SAXReader saxReader = new SAXReader();
        try {
            // 一定要注意路径!!!吃过亏
            Document document = saxReader.read(Dom4jParseUserXmlTest.class.getClassLoader().getResource("static/user.xml"));
            Element rootElement = document.getRootElement();
            System.out.println("1.----->user.xml根节点名字:"+rootElement.getName());
            System.out.println("------------------------");
            System.out.println("2.----->获取根标签users的子标签列表");
            List usersSubElementList = rootElement.elements();
            for (Element userElement : usersSubElementList) {
                System.out.println("users标签的子标签的名字是:"+userElement.getName());
                System.out.println("users标签的子标签的id属性值是:"+userElement.attributeValue("id"));
                System.out.println("users标签的子标签的country属性值是:"+userElement.attributeValue("country"));

                System.out.println("------------------");
                System.out.println("3.----->获取user的子标签列表");
                List userSubElementList = userElement.elements();
                for (Element userSubelement : userSubElementList) {
                    System.out.println("user标签下的子标签名字是:"+userSubelement.getName());
                    System.out.println("user标签下的子标签文本是:"+userSubelement.getText());
                }
            }
            // 获取users标签的第一个user标签
            Element firstUserElement = rootElement.element("user");
            // 第一个user标签的子标签password文本
            String password = firstUserElement.elementText("password");
            System.out.println(password);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

 运行后结果:

1.----->user.xml根节点名字:users
------------------------
2.----->获取根标签users的子标签列表
users标签的子标签的名字是:user
users标签的子标签的id属性值是:TB10001
users标签的子标签的country属性值是:Chinese
------------------
3.----->获取user的子标签列表
user标签下的子标签名字是:id
user标签下的子标签文本是:10001
user标签下的子标签名字是:name
user标签下的子标签文本是:admin
user标签下的子标签名字是:password
user标签下的子标签文本是:111111
user标签下的子标签名字是:salary
user标签下的子标签文本是:salary > 15000 & salary < 30000
users标签的子标签的名字是:user
users标签的子标签的id属性值是:TB10002
users标签的子标签的country属性值是:Chinese
------------------
3.----->获取user的子标签列表
user标签下的子标签名字是:id
user标签下的子标签文本是:10002
user标签下的子标签名字是:name
user标签下的子标签文本是:tonny
user标签下的子标签名字是:password
user标签下的子标签文本是:666666
user标签下的子标签名字是:salary
user标签下的子标签文本是:salary > 15000 & salary < 3000
111111

进程已结束,退出代码为 0

3.dom4j结合XPath解析XML

XPath可以使用路径表达式来选取XML文档中的元素或者属性节点,节点是沿着路径来选取的。

XPath的官方文档地址XPath 教程 (zvon.org)

dom4j集成XPath

maven下载依赖


        
            jaxen
            jaxen
            2.0.0
        

dom4j提供基于XPath的API

Document/Element关于XPath的api

        

Node selectSingleNode(String xpathExpression); //根据xPath表达式获取单个标签(元素/节点)

List selectNodes(String xpathExpression); //根据xPath表达式获取多个标签(元素/节点)

XPath的语法

  • 绝对路径方式,以/开头的路径表示绝对路径,绝对路径是从根元素开始写。例如/元素/子元素/子子元素..
  • 相对路径方式:相对于当前节点的元素继续查找的节点,不以/开头,../表示上一个元素,./表示当前元素
  • 全文搜索路径方式:例如//子元素,//子元素//子子元素,//子元素/子子元素//表示无论中间有多少层,直接获取所有子元素所有满足条件的元素/表示只找一层
  • 语(条件筛选)方式例如//元素[@attr1='value]

完整代码

package com.itheima.demo.dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.util.List;

public class Dom4jXPathParseUserXmlTest {
    public static void main(String[] args) {
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(Dom4jParseUserXmlTest.class.getClassLoader().getResource("user.xml"));
            System.out.println("1.------>使用绝对路径方式查找元素");
            // Node继承Element,也可以换一种写法
            // Node selectSingleNode = document.selectSingleNode("/users/user/password");
            Element element = (Element)document.selectSingleNode("/users/user/password");
            // 获取密码
            String password = element.getText();
            System.out.println("第一个用户的密码是:"+password);

            System.out.println("2.------>使用相对路径方式查找元素");
            Element node =(Element) element.selectSingleNode("../salary");
            System.out.println(node.getText());

            System.out.println("3.------>使用相对路径方式查找元素");
            System.out.println("获取所有ID元素的文本");
            List idNodeList = document.selectNodes("//id");
            for (Node node1 : idNodeList) {
                Element idElement = (Element) node1;
                System.out.println(idElement.getText());
            }
            System.out.println("4.------>谓语(条件筛选)方式查找元素");
            System.out.println("获取user id属性为TB10001的用户属性信息");
            Element TB10001IDElement = (Element)document.selectSingleNode("//user[@id='TB10001']");
            List elementList = TB10001IDElement.elements();
            for (Element userSubElement : elementList) {
                System.out.println("user子标签的名称"+userSubElement.getName());
                System.out.println("user子标签的文本"+userSubElement.getText());
            }
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }

    }
}

运行后结果: 

C:\Users\YZH\.jdks\openjdk-17.0.1\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2023.1\lib\idea_rt.jar=63970:D:\IDEA\IntelliJ IDEA 2023.1\bin" -Dfile.encoding=UTF-8 -classpath D:\黑马下半\huizhi-learning\maven_java\target\test-classes;D:\黑马下半\huizhi-learning\maven_java\target\classes;D:\maven-repository\org\junit\jupiter\junit-jupiter-api\5.9.2\junit-jupiter-api-5.9.2.jar;D:\maven-repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;D:\maven-repository\org\junit\platform\junit-platform-commons\1.9.2\junit-platform-commons-1.9.2.jar;D:\maven-repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;D:\maven-repository\org\dom4j\dom4j\2.1.4\dom4j-2.1.4.jar;D:\maven-repository\jaxen\jaxen\2.0.0\jaxen-2.0.0.jar com.itheima.demo.dom4j.Dom4jXPathParseUserXmlTest
1.------>使用绝对路径方式查找元素
第一个用户的密码是:111111
2.------>使用相对路径方式查找元素
salary > 15000 & salary < 30000
3.------>使用相对路径方式查找元素
获取所有ID元素的文本
10001
10002
4.------>谓语(条件筛选)方式查找元素
获取user id属性为TB10001的用户属性信息
user子标签的名称id
user子标签的文本10001
user子标签的名称name
user子标签的文本admin
user子标签的名称password
user子标签的文本111111
user子标签的名称salary
user子标签的文本salary > 15000 & salary < 30000

进程已结束,退出代码为 0

XML文件




    
        10001
        admin
        111111
    
        salary > 15000 & salary < 30000
    
    
        10002
        tonny
        666666
        
        salary > 15000 & salary < 3000
    

你可能感兴趣的:(xml,前端,javascript)