二、Java框架基础02 XML

二、XML

2.1 XML 简介

XML 即可扩展标记语言,一种简单的数据存储语言,使用一系列简单的标记来描述结构化数据

XML 的特点

  • XML 与操作系统,编程语言的开发平台无关
  • 规范统一,实现不同系统之间的数据交互

2.1.1 XML 的文档结构

以下是 XML 代码描述图书的信息

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book id="bk101">
        <title>.NET高级编程</title>
        <author>王珊</author>
        <description>包含C#框架和网络编程等</description>
    </book>
    <book id="bk102">
        <title>XML基础编程</title>
        <author>李明明</author>
        <description>包含XML基础概念和基本用法</description>
    </book>
</books>
  • 通过以上代码来具体了解 XML 文档结构

2.1.2 XML 声明

  • <?xml version="1.0" encoding="UTF-8"?> 表示 XML 声明,用于标明这是一个 XML 文件
  • XML 声明主要有以下部分组成
    • version 文档符合 XML 1.0 规范
    • encoding 文档字符编码,默认为 UTF-8
  • 对于任何一个 XML 文档,都是固定格式

2.1.3 标签

  • XML 中,通过用尖括号 <> 括起来的各种标签来标记数据
  • 标签必须成对使用,必须有开始标签 <> 和 结束标签 </>
  • 标签之间是标签描述的内容
  • 例如 <author>王珊</author> 则表示作者信息

2.1.4 元素

  • XML 文档的主要部分是元素

  • 元素由开始标签、结束标签和元素内容注册

  • 元素内容指开始标签和结束标签之间的内容,可以包含子元素,字符数据等

  • 元素的命名规则如下

    • 名称中可以包含字母、数字或其他的字符
    • 名称不能以数字或标点符号开始
    • 名称不能以字符 xmlXML 等开始
    • 名称中不能包含空格
    • 元素允许是空元素,如 <title></title><title/>
  • 根元素

    • 每个 XML 文档必须有且仅有一个根元素,如 <books></books>
    • 根元素是一个完全包括文档中其他所有元素的元素
    • 根元素的起始标签要放在所有其他元素的起始标签之前
    • 根元素的结束标签要放在所有其他元素的结束标签之后
  • 属性

    • <book id="bk101"> 标签中使用 id 属性描述图书的编号信息
    • 属性的定义语法如下
    <元素名 属性名="属性值">
    
    • 属性值用双引号包裹
    • 一个元素可以有多个属性,多个属性之间用空格隔开
    • 元素中不能直接包含 <"&
    • 属性只能加在元素的起始标签上
  • XML 中的特殊字符的处理

    • 在 XML 中,有时在元素的文本中会涉及一些特殊字符 < > ' " &
    • 使用这些字符,需要用到 XML 中的预定义实体代替
    • XML 中的预定义实体和特殊字符的对应关系
    特殊字符实体名称
    <<
    >>
    &&amp;
    "&quot;
    &apos;
  • CDATA - (未解析)字符数据

    • 术语 CDATA 是不应该由 XML 解析器解析的文本数据。

    • <& 字符在 XML 元素中都是非法的。

    • < 会产生错误,因为解析器会把该字符解释为新元素的开始。

    • & 会产生错误,因为解析器会把该字符解释为字符实体的开始。

    • CDATA 部分中的所有内容都会被解析器忽略

  • CDATA 语法格式如下

    <![CDATA[要显示的字符]]>
    

2.2 解析 XML 概述

在实际应用当中,经常需要对 XML 文档进行各种操作

如在应用程序启动时去读取 XML 配置文件信息

或把数据库中的内容读取出来转为 XML 文档形式

这种情况就要运用到 XML 文档的解析技术

目前常用的 XML 解析技术有 4 种

2.2.1 DOM

  • DOM 是基于 XML 的树结构来完成解析的
  • DOM 解析 XML 文档时,会根据读取的文档,构建一个驻留内存的树结构
  • 使用 DOM API 可以操作这个树结构
  • 支持删除、修改、重新排列等多种功能
  • 但 DOM 解析同时也比较消耗资源

2.2.2 SAZ

  • SAZ 是基于事件的解析,为了解决 DMO 解析的资源消耗而出现的
  • SAZ 是通过事件处理器完成对文档的解析
  • SAZ 不用事先调入整个文档,所以它的优势就是占用资源少,内存消耗小
  • 在解析数据量较大的 XML 文档时会采用这种方式

2.2.3 JDOM

  • JDOM 是针对 Java 的特定文档模型
  • 它简化了与 XML 的交互并且币使用 DOM 更快
  • JDOM 仅使用具体类而不使用接口,在某方面简化了 API
  • 但是也限制了灵活性
  • API 大量使用了 Java 集合类型,对于属性这类的 Java 开发者而简化了使用

2.2.4 DOM4J

  • DOM4J 是一个非常优秀的 Java XML API
  • 具有性能优异、功能强大、易用的特点
  • DOM4J 用于在 Java 平台上使用 Java 集合框架处理 XML、XPath 和 XSLT
  • DOM4J 大量使用接口,面向接口编程使它币 JDOM 更加灵活

2.3 使用 DOM 读取 XML 数据

2.3.1 DOM 概念

  • DOM 即文档对象模型
  • DOM 把 XML 文件映射成一课倒挂的 “树”
  • 以根元素为根节点,每个节点都以对象形式存在
  • 通过存取这些对象就能存取 XML 文档的内容
  • 例如,创建文件 book.xml 并保存,book.xml 内容如下
<?xml version="1.0" encoding="UTF-8"?>
<book id="bk101">
    <title>三国演义</title>
    <author>罗贯中</author>
    <price>30元</price>
</book>
  • book.xml 对应的 DOM 树结构

image-20230722163108349

2.3.2 使用 DOM 读取手机收藏信息

  • 可以使用 JAXP 来解析 XML
  • JAXP 包含 3 个包,这 3 个包都在 JDK 中
    • org.w3c.dom:W3C 推荐的用于使用 DOM 解析 XML 文档的接口
    • org.xml.sax:用于使用 SAZ 解析 XML 文档的接口
    • javax.xml.parsers:解析其工厂工具,获得并配置特殊的解析器
  • 使用 DOM 解析 XML 时需要导入这些包中相关的类
  • JAXP 会把 XML 文档转换成一个 DOM 树
  • 使用 DOM 解析 XML 文档的步骤如下
    • 创建解析器工厂对象,即 DocumentBuilderFactory 对象
    • 由解析器工厂对象创建解析器对象,即 DocumentBuilder 对象
    • 由解析器对象对指定的 XML 文件进行解析,构建相应的 DOM 数,创建 Document 对象
    • 以 Document 对象为起点,对DOM 树的节点进行增加、删除、修改、查询等操作

2.3.3 使用 DOM 读取 XML 数据,使用 DOM 读取手机收藏信息中的品牌和型号信息 示例

XML 文档代码如下

<?xml version="1.0" encoding="UTF-8"?>
<PhoneInfo>
    <Brand name="华为">
        <Type name="P90"/>
    </Brand>
    <Brand>
        <Type name="iPhone Z"/>
        <Type name="iPhone ZL"/>
    </Brand>
</PhoneInfo>

手机收藏信息的 XML 文档对应的 DOM 树主要结构

image-20230722164954351

根据使用 DOM 解析 XML 的文档步骤,关键代码如下

package Test01;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;

public class Test01 {
    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
        //得到 DOM 解析器的工厂实例
        DocumentBuilderFactory dbf=DocumentBuilderFactory.newDefaultInstance();
        //从 DOM 工厂获取 DOM 解析器
        DocumentBuilder db=dbf.newDocumentBuilder();
        //解析 XML 文档,等到一个 Document 对象,即DOM数
        //xml 文件位置,从 src包下开始
        Document doc= db.parse("src/main/java/Test01/收藏信息.xml");
        //等到所有的 Brand 节点列表信息
        NodeList brandList=doc.getElementsByTagName("Brand");
        //循环 Brand 信息
        for (int i=0; i<brandList.getLength();i++){
        //获取第 i 个 Brand 元素信息
            Node brand=brandList.item(i);
        //获取第 i 个 Brand 元素的 name属性
            Element element= (Element) brand;
            String attrValue=element.getAttribute("name");
         //获取第 i 个 Brand 元素的所有子元素的 name 属性值
         NodeList types=element.getChildNodes();
            for (int j = 0; j <types.getLength() ; j++) {
                    Node node=types.item(j);
                    if (node.getNodeType()==Node.ELEMENT_NODE){
                        Element typeElement= ((Element) types.item(j));
                        String type=typeElement.getAttribute("name");
                        System.out.println("手机"+attrValue+type);
                    }
            }
        }
    }
}

2.3.4 使用 DOM 解析 XML 时主要使用以下对象

Node 对象

  • Node 对象是 DOM 结构中的基本对象,代表了文档树中的一个抽象节点
  • Node 对象的主要方法如下
方法名说明
getChildNodes()返回包含此节点所有子节点 NodeList
getFirstChild()如果节点存在子节点,则返回第一个子节点
getLastChild()如果节点存在子节点,则返回最后一个子节点
getNextSibling()返回在 DOM 树中这个节点的下一个兄弟节点
getPreviousSibling()返回在 DOM 树中这个节点的上一个兄弟节点
getNodeName()返回节点的名称
getNodeValue()返回节点的值
getNodeType()返回节点的类型

NodeList 对象

  • NodeList 对象是指包含了一个或多个节点 (Node) 列表
  • 可以通过方法来获取列表中的元素
  • NodeList 对象的常用方法
方法名说明
getLength()返回列表长度
item(int idnex)返回指定位置的 Node 对象

Document 对象

  • Document 对象代表整个 XML 文档
  • 所有其他的 Node 都以一定的顺序包含在 Document 对象之内
  • 它是对 XML 文档进行操作的起点,先通过解析 XML 源文件获取 Document 对象然后来执行后续的操作
  • Document 对象的主要方法
方法名说明
getElementsByTagName(String name)返回一个 NodeList 对象,包含所有给定标签名的标签
getDocumentElement()返回一个代表这个 DOM 树的根节点的 Element 对象

Element 对象

  • Element 对象代表 XML了文档中的 标签元素
  • 在标签中可以包含属性,因而 Element 对象中也有存取属性的方法
  • Element 对象方法如下
方法名说明
getAttribute(String attributename)返回标签中给定属性名称的属性的值
getElementsByTagName(String name)返回具有给定标签名称的所有后代 Elements 的 NodeList

注意事项

  • XML 文档中的空白符也会被作为对象映射在 DOM 树中
  • 所以直接调用 Node 对象的 getChildNodes() 方法有时会出现一些问题
  • 解决方案如下
    • 使用 Element 的 getElementByTagName(String name),返回的 NodeList 对象就是所期待的对象
    • 调用 Node 的 getChildNodes() 方法得到 NodeList 对象,每次通过 item() 方法提取 Node 对象然后判断
    • 判断 node.getNodeType()==Node.ELEMENT_NODE 即判断是否为元素节点

2.4 使用 DOM4J 解析 XML

2.4.1 DOM4J API 概述

  • 使用 DOM4J 只要了解 XML-DOM 模型就能使用
  • DOM4J 主要接口都在 org.dom4j 这个包里定义
说明
Attribute定义了 XML 属性
Branch为能够包含子节点的节点,定义了一个公共行为
CDATA定义了 XML CDATA 区域
CharacterData是一个标识接口,标识基于字符的节点,如 CDATA、Comment 和 Text
Comment定义了 XML 注释的行为
Document定义了 XML 文档
DocumentType定义 XML DOCTYPE 声明
Element定义了 XML 元素
ElementHandler定义了 Element 对象的处理器
ElementPath被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
Entity定义 XML 实体
Node为 dom4j 中所有的 XML 节点定义了多态行为
NodeFilter定义了在 dom4j 节点中产生的一个滤镜或谓词的行为
ProcessingInstruction定义 XML 处理指令
Text定义了 XML 文本节点
Visitor用于实现 Visitor 模式
XPath通过分析一个字符串提供一个 XPath 表达式
  • 使用这些需要提前导入一个 dom4j 的包
<!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version>
</dependency>

2.4.2 使用 DOM4J 操作 XML 数据

1、Document 对象相关

  • 读取 XML 文件,获得 Document 对象
SAXReader reader=new SAXReader();
Document document=reader.read(new File("input.xml"));

2、节点相关

  • 获得文档的根元素
Element rootElm=document.getRootElement();
  • 取得某节点的单个子节点
Element memberElm=rootElm.element("member"); //member 是节点名
  • 取得节点的文字
String text=emeberElm.getText();
//或者用下面这种方式
//取得根元素下的 name 子节点的文字
String text=rootElm.elementText("name");
  • 在某个节点下添加子节点,newMemberElm 是某个已存在的节点
Element ageElm=newMemberElm.addELment("age");
  • 设置文字节点
ageElm.setText("29");
  • 删除某节点
parentElm.remove(childElm);// childElm 是待删除的节点,parentElm是其父节点

3、属性相关

  • 取得某节点下的某属性
Element root=document.getRootElement();
Attribute attribute=toor.attribute("size"); //属性名 size
  • 取得属性的值
String text=attribute.getText();
//也可以使用
String text2=root.element("name").attributeValue("firstname");
  • 为某节点添加属性
newMemberElm.addAttribute("name","learningdom4j");
  • 设置属性的值
Attribute attribute=root.attribute("name");
attribute.setText("learningdom4j");
  • 删除某属性
Attribute attribute=root.attribute("size"); //属性名saize
root.remove(attribute)

e attribute=toor.attribute(“size”); //属性名 size


- 取得属性的值

~~~java
String text=attribute.getText();
//也可以使用
String text2=root.element("name").attributeValue("firstname");
  • 为某节点添加属性
newMemberElm.addAttribute("name","learningdom4j");
  • 设置属性的值
Attribute attribute=root.attribute("name");
attribute.setText("learningdom4j");
  • 删除某属性
Attribute attribute=root.attribute("size"); //属性名saize
root.remove(attribute)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/44257.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[数学建模] [2019年A 模拟练习][层次分析法、熵值法、多目标优化、主成分分析法] 4. 深圳居民健康水平评估与测控模型研究

1、前言 2019年“深圳杯”数学建模挑战赛A题 原题&#xff0c;这个是当时学校内部校赛所作&#xff0c;为了拿到参加国赛名额&#xff0c;也权当是做一个简单的练手。 本次练习属于综合评判类&#xff0c;常用的方法无非 层次分析法、熵值法、多目标优化、主成分分析法 等&am…

引入第三方字体库 第三方字体库Google Fonts

googlefonts官方网站 googlefonts中国网站 本人是在微信小程序中引入 在static中建一个文件夹font-family 例如字体链接&#xff1a;https://fonts.font.im/css?familyKirangHaerang 将该链接的返回的资源的复制到css文件中 font-family.css /* [0] */ font-face {font-fam…

MURF20100CTR-ASEMI快恢复对管封装、尺寸、参数

编辑&#xff1a;ll MURF20100CTR-ASEMI快恢复对管封装、尺寸、参数 型号&#xff1a;MURF20100CTR 品牌&#xff1a;ASEMI 芯片个数&#xff1a;2 芯片尺寸&#xff1a;102MIL*2 封装&#xff1a;TO-220F 恢复时间&#xff1a;50ns 工作温度&#xff1a;-50C~150C 浪…

VSCode_常用插件_最新推荐

本文介绍前端开发领域常用的一些VSCode插件&#xff0c;插件是VSCode最重要的组成部分之一&#xff0c;本文列出了个人觉得是有用或有趣的一些插件。 一、代码管理相关插件 1、GitLens — Git supercharged 该插件增强了 VS Code 中的 Git&#xff0c;通过丰富的可视化和强…

Python 快速简单搭建HTTP本地服务器,内网通过浏览器访问

1 下载python https://www.python.org/downloads/ 2 安装python&#xff0c;安装时候选择把path加入电脑环境变量 3 由于python内建了简单http服务包&#xff0c;因此对于python来说&#xff0c;只需输入一行命令&#xff0c;就能轻松打开http服务。当然&#xff0c;要运行网页…

SQL-每日一题【619.只出现一次的最大数字】

题目 MyNumbers 表&#xff1a; 单一数字 是在 MyNumbers 表中只出现一次的数字。 请你编写一个 SQL 查询来报告最大的 单一数字 。如果不存在 单一数字 &#xff0c;查询需报告 null 。 查询结果如下例所示。 示例 1&#xff1a; 示例 2&#xff1a; 解题思路 1.题目要求我…

CPU渲染or GPU渲染,你选对了吗?看完这六点就懂了!

在进行动画或效果图渲染时&#xff0c;选择适合的渲染方式对于项目的速度和质量至关重要。CPU渲染和GPU渲染作为两种主要的渲染方式&#xff0c;哪一种更适合你现在的情况&#xff1f;接下来我将从以下六个方面带大家深入了解&#xff0c;看完就知道怎么选了。 1.渲染原理 CPU…

gradio初体验

背景 近期随着很多开源大模型的出现&#xff0c;对于其如何落地&#xff0c;或者说充分地去挖掘其实际应用领域和商业价值变得格外重要。于是乎&#xff0c;对于不懂技术的前方市场或销售人员&#xff0c;如何在没有形成AI产品之前向其展示算法模型效果呢&#xff1f;这时候gr…

Spring 多数据源方法级别注解实现

Spring框架提供了多种数据源管理方式&#xff0c;其中多数据源管理是其中之一。多数据源管理允许应用程序使用多个数据源&#xff0c;而不是只使用一个数据源&#xff0c;从而提高了应用程序的灵活性和可靠性。 多数据源管理的主要目的是让应用程序能够在不同的数据库之间切换&…

【RabbitMQ(day1)】RabbitMQ的概述和安装

入门RabbitMQ 一、RabbitMQ的概述二、RabbitMQ的安装三、RabbitMQ管理命令行四、RabbitMQ的GUI界面 一、RabbitMQ的概述 MQ&#xff08;Message Queue&#xff09;翻译为消息队列&#xff0c;通过典型的【生产者】和【消费者】模型&#xff0c;生产者不断向消息队列中生产消息&…

SIGIR 2023 | 语音让对话推荐更easy,火山语音联合新加坡科学研究院发布业内首个语音对话推荐数据集

近年来&#xff0c;推荐系统在工业界取得了巨大成功&#xff0c;甚至成为互联网发展中不可或缺的增长引擎&#xff0c;基于此研究者们也在积极探索推荐系统的新形态&#xff0c;其中对话推荐系统&#xff08;Conversational Recommender System&#xff0c;简称CRS&#xff09;…

Mac上安装sshfs

目录 写在前面安装使用参考完 写在前面 1、本文内容 Mac上安装sshfs 2、平台 mac 3、转载请注明出处&#xff1a; https://blog.csdn.net/qq_41102371/article/details/130156287 安装 参考&#xff1a;https://ports.macports.org/port/sshfs/ 通过port安装 点击啊insta…

Qt/C++音视频开发49-多级连保存和推流设计(同时保存到多个文件/推流到多个平台)

一、前言 近期遇到个用户需要多级联的保存和推流&#xff0c;在ffmpegsave多线程保存类中实现这个功能&#xff0c;越简单越好&#xff0c;就是在推流的同时&#xff0c;能够开启自动转储功能&#xff0c;一边推流的同时一边录像保存到本地视频文件。最初设想的一个方案是new两…

【MySQL】之复合查询

【MySQL】之复合查询 基本查询多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使用子查询 合并查询小练习 基本查询 查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还要满足他们的姓名首字母为大写的J按照部门号升序而雇员的工资降序排序使用…

源码对接微软Azure OpenAI 规范注意点

众所周知&#xff0c;我们是访问不通OpenAI官方服务的&#xff0c;但是我们可以自己通过代理或者使用第三方代理访问接口 现在新出台的规定禁止使用境外的AI大模型接口对境内客户使用&#xff0c;所以我们需要使用国内的大模型接口 国内的效果真的很差&#xff0c;现在如果想合…

深圳湾晚霞下的职场分享:723深圳COC社区活动回顾

文章目录 深圳湾晚霞下的职场分享&#xff1a;723深圳COC社区活动回顾前言人物观察架构师李肯连续创业者石云升鸿蒙布道师坚果 职友分享个人分享 后记最后分享一波&#xff1a;深圳湾晚霞美图&#xff01; 深圳湾晚霞下的职场分享&#xff1a;723深圳COC社区活动回顾 前言 ​…

vue项目入口和个文件之间的关系

vue项目入口和个文件之间的关系 1、代码的执行顺序和引入关系 1、代码的执行顺序和引入关系

时钟分频器

文章目录 一、8分频二、n倍时钟分频器 一、8分频 8倍时钟分频器是一种电路或设备&#xff0c;用于将输入时钟信号的频率分成原来的1/8。它可以在数字电子系统中用于将高频时钟信号降低到较低的频率&#xff0c;以满足特定的系统需求。 在这个电路中&#xff0c;CLK是输入的时钟…

【wxWidgets】剪贴板和拖放操作

【wxWidgets】剪贴板和拖放操作 使用剪贴板传输数据时应用程序间的一种交互方式 剪贴板和拖放操作在wxWidgets中共享了一些类来实现数据的传输 数据对象 wxDataObject类时剪贴板操作和拖放操作的核心&#xff0c;该类实例代表了拖放操作中鼠标拖拽的事物和剪贴板中拷贝和粘贴…

10分钟搭建链路追踪平台

随着项目越来越多&#xff0c;相互调用越来越复杂&#xff0c;搭建一个可视化的链路追踪平台显得尤为重要&#xff0c;今天给大家介绍的是zipkin&#xff0c;一个轻量级的零侵入的链路追踪平台&#xff0c;看我怎么10分钟给大家搭建出来。 1&#xff0c;介绍 zipkin官网&…