技术:Java-Web基础|XML解析(二)之JAXP-DOM

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: XML是标记型文档,js 使用 dom 解析标记型文档是根据 html 的层级结构,在内存中分配一个属性结构,把 html 的标签,属性和文本都封装成 document 对象、element 对象,属性对象、文本对象,node 节点对象。「XML」解析技术xml的解析技术:dom 和 sax。

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包中找到解析方法。

image.png


「步骤」

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

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

3、获取根元素集合

4、解析处理


2.2 创建实验xml

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

<?xmlversion="1.0" encoding="utf-8"?><persons><personsid="001"><name>张小帅</name><sex></sex><age>18</age></person><personsid="002"><name>刘晓萌</name><sex></sex><age>21</age></person><personsid="003"><name>王老四</name><sex></sex><age>38</age></person></persons>


2.3 解析技术DOM

创建DomParserXmlTest.java,内容如下。

packagecom.liuyc.tooljdk.xml;
importorg.w3c.dom.*;
importorg.xml.sax.SAXException;
importjavax.xml.parsers.DocumentBuilder;
importjavax.xml.parsers.DocumentBuilderFactory;
importjavax.xml.parsers.ParserConfigurationException;
importjava.io.IOException;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.Map;
/*** <p> DomParserXmlTest </p>*/publicclassDomParserXmlTest {
publicstaticvoidmain(String[] args) {
StringxmlPath="./tool-jdk8/src/main/java/com/liuyc/tooljdk/xml/persons.xml";
try {
// 1、创建 DOM 解析器的工厂,得到 DOM 解析器对象DocumentBuilderbuilder=DocumentBuilderFactory.newInstance().newDocumentBuilder();
// 2、解析 XML 文档,得到代表整个文档的 Document 对象,将其放在内存中Documentdocument=builder.parse(xmlPath);
// 3、获取根元素 personsSystem.out.println("----------------------------------------------------------------------");
Elementroot=document.getDocumentElement();
System.out.println("根元素节点名称:"+root.getNodeName());
System.out.println("根元素节点类型(是一个元素:Element = 1):"+root.getNodeType());
System.out.println("----------------------------------------------------------------------");
NodeListpersonNode=document.getElementsByTagName("person");
System.out.println("person节点数量:"+personNode.getLength());
NodepersonEle=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("----------------------------------------------------------------------");
NodeListnames=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、解析NodeListlist=root.getChildNodes();
ArrayList<Map<String, Object>>arr=newArrayList<>();
for (inti=0; i<list.getLength(); i++) {
// 遍历所有person节点Nodeitem=list.item(i);
if (item.getNodeType() ==Node.ELEMENT_NODE) {
Map<String, Object>map=newHashMap<>();
NamedNodeMapattributes=item.getAttributes();
// 遍历所有person属性for (intj=0; j<attributes.getLength(); j++) {
NodenodePerson=attributes.item(j);
map.put(nodePerson.getNodeName(), nodePerson.getNodeValue());
                    }
// 遍历所有person节点的内容NodeListlist2=item.getChildNodes();
for (intj=0; j<list2.getLength(); j++) {
Nodeitem2=list2.item(j);
if (item2.getNodeType() ==Node.ELEMENT_NODE) {
Nodenode=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 (ParserConfigurationExceptione) {
// TODO Auto-generated catch blocke.printStackTrace();
        } catch (SAXExceptione) {
// TODO Auto-generated catch blocke.printStackTrace();
        } catch (IOExceptione) {
// TODO Auto-generated catch blocke.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

// --------------------------------------------------------------------------// 5、为person新增一个标签:职级等级(position_level),他的内容是:三级// 创建position_level元素ElementpLevel=document.createElement( "position_level" );
// 创建position_level的文本TextpLevelText=document.createTextNode( "三级" );
// 把文本添加到position_levelpLevel.appendChild(pLevelText);
// 把 position_level 添加到 索引为1的 person 下面personEle.appendChild(pLevel);
// 回写 xmlTransformerFactorytransformerFactory=TransformerFactory.newInstance();
Transformertransformer=transformerFactory.newTransformer();
transformer.transform(newDOMSource(document), newStreamResult(xmlPath));
// --------------------------------------------------------------------------

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

image.png

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


2.6 修改节点

「步骤」

1、得到age元素

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

3、回写xml,使之生效

// --------------------------------------------------------------------------// 6、修改第一个人的年龄为28System.out.println("----------------------------------------------------------------------");
// 得到ageNodeageNode=document.getElementsByTagName("age").item(0);
System.out.println("原始年龄:"+ageNode.getTextContent());
// 修改age值ageNode.setTextContent("28");
System.out.println("修改后的年龄:"+ageNode.getTextContent());
// 回写xmlTransformerFactorytransformerFactory=TransformerFactory.newInstance();
Transformertransformer=transformerFactory.newTransformer();
transformer.transform(newDOMSource(document), newStreamResult(xmlPath));
// --------------------------------------------------------------------------

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

原始年龄:18修改后的年龄:28

image.png

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


2.7 删除节点

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


「步骤」

1、获取position_level节点元素

2、得到position_level父节点

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

4、回写xml,使之生效


// 7、删除position_level节点System.out.println("----------------------------------------------------------------------");
// 获取position_level节点元素NodepLevel=document.getElementsByTagName("position_level").item(0);
// 得到position_level父节点NodepLevelParentNode=pLevel.getParentNode();
// 使用父节点删除当前节点操作pLevelParentNode.removeChild(pLevel);
// 回写xmlTransformerFactorytransformerFactory=TransformerFactory.newInstance();
Transformertransformer=transformerFactory.newTransformer();
transformer.transform(newDOMSource(document), newStreamResult(xmlPath));

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

image.png


3 DOM技术

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

针对元素有如下方法:

image.png

针对节点有如下方法:

image.png

DocumentBuilder API

image.png

DocumentBuilderFactory API

image.png

w3c标准

image.png


相关文章
|
13天前
|
JavaScript 安全 Java
智慧产科一体化管理平台源码,基于Java,Vue,ElementUI技术开发,二开快捷
智慧产科一体化管理平台覆盖从备孕到产后42天的全流程管理,构建科室协同、医患沟通及智能设备互联平台。通过移动端扫码建卡、自助报道、智能采集数据等手段优化就诊流程,提升孕妇就诊体验,并实现高危孕产妇五色管理和孕妇学校三位一体化管理,全面提升妇幼健康宣教质量。
42 12
|
17天前
|
XML JSON Java
Java中Log级别和解析
日志级别定义了日志信息的重要程度,从低到高依次为:TRACE(详细调试)、DEBUG(开发调试)、INFO(一般信息)、WARN(潜在问题)、ERROR(错误信息)和FATAL(严重错误)。开发人员可根据需要设置不同的日志级别,以控制日志输出量,避免影响性能或干扰问题排查。日志框架如Log4j 2由Logger、Appender和Layout组成,通过配置文件指定日志级别、输出目标和格式。
|
1月前
|
存储 Java 计算机视觉
Java二维数组的使用技巧与实例解析
本文详细介绍了Java中二维数组的使用方法
52 15
|
7天前
|
Java API 数据处理
深潜数据海洋:Java文件读写全面解析与实战指南
通过本文的详细解析与实战示例,您可以系统地掌握Java中各种文件读写操作,从基本的读写到高效的NIO操作,再到文件复制、移动和删除。希望这些内容能够帮助您在实际项目中处理文件数据,提高开发效率和代码质量。
15 0
|
2月前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
289 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
1月前
|
算法 搜索推荐 Java
【潜意识Java】深度解析黑马项目《苍穹外卖》与蓝桥杯算法的结合问题
本文探讨了如何将算法学习与实际项目相结合,以提升编程竞赛中的解题能力。通过《苍穹外卖》项目,介绍了订单配送路径规划(基于动态规划解决旅行商问题)和商品推荐系统(基于贪心算法)。这些实例不仅展示了算法在实际业务中的应用,还帮助读者更好地准备蓝桥杯等编程竞赛。结合具体代码实现和解析,文章详细说明了如何运用算法优化项目功能,提高解决问题的能力。
73 6
|
1月前
|
SQL Java 数据库连接
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
338 11
|
1月前
|
存储 算法 搜索推荐
【潜意识Java】期末考试可能考的高质量大题及答案解析
Java 期末考试大题整理:设计一个学生信息管理系统,涵盖面向对象编程、集合类、文件操作、异常处理和多线程等知识点。系统功能包括添加、查询、删除、显示所有学生信息、按成绩排序及文件存储。通过本题,考生可以巩固 Java 基础知识并掌握综合应用技能。代码解析详细,适合复习备考。
25 4
|
1月前
|
存储 分布式计算 Hadoop
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
61 7
|
1月前
|
存储 Java
【潜意识Java】期末考试可能考的选择题(附带答案解析)
本文整理了 Java 期末考试中常见的选择题,涵盖数据类型、控制结构、面向对象编程、集合框架、异常处理、方法、流程控制和字符串等知识点。每道题目附有详细解析,帮助考生巩固基础,加深理解。通过这些练习,考生可以更好地准备考试,掌握 Java 的核心概念和语法。
37 1

热门文章

最新文章

推荐镜像

更多