二、Java框架基础 XML

二、 XML

2.1 XML 简介

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

  • 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>

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中,通过尖括号<>括起来的各种(Tag)来标记数据。
  • **标签必须成对使用,必须有开始标签 <> 和 结束标签 </>**
  • 标签成对使用来界定字符数剧。

注意:XML 标签必须正确结束并正确地嵌套,缺少结束标签及如下的嵌套方式是错误的。

xml 复制代码
<title>
    <name>
       XML 编程
    </name>
</title>

2.1.4 元素

  • XML 文档的主要部分是元素,如"王珊"就是一个元素。

  • 元素由开始标签、结束标签和元素内容组成。

  • 元素命名规则如下:

    • 名称中可以包含字母、数字或其他的符号。
    • 名称不能以数字或标点符号开始。
    • 名称不能以字符"xml"(或XML、Xml)开始。
    • 名称中不能包含空格
  • 元素允许是空元素,如的元素写法是允许的。

2.1.5 根元素

每一个XML文档必须有且仅有一个根元素,如""。

  • 根元素的特点:
    • 根元素是一个完全包括文档中其他所有元素的元素。
    • 根元素的起始标签要放在所有其他元素的起始标签之前。
    • 根元素的结束标签要放在其他元素的结束标签之后。

2.1.6 属性

  • 语法:
xml 复制代码
<元素名 属性名="属性值">
  • 属性值同双引号包裹。

注意:

  1. 一个元素可以有多个属性,多个属性之间用空格隔开,

格式:

xml 复制代码
<元素名 属性名="属性值" 属性名="属性值"/>
  1. 属性值中不能直接包含<、"、&。
  2. 属性可以加载任何一个元素的起始标签上,但不能加在结束标签上。

2.1.7 XML 中的特殊字符的处理

  • 在 XML 中,有时在元素的文本中会涉及一些特殊字符 < > ' " &
  • 使用这些字符,需要用到 XML 中的预定义实体代替
  • XML 中的预定义实体和特殊字符的对应关系
特殊字符 实体名称
< <
> >
& &
" "
' '

2.1.8 格式良好的XML文档

  • 格式良好的XML文档需要遵循如下规则:
    • 有XML声明语句。
    • 有且仅有一个根元素。
    • 标签大小写敏感。
    • 属性值用双引号包裹。
    • 标签成对/空标签关闭。
    • 元素正确嵌套。

2.2 解析 XML 概述

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

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

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

这些时候都会用到 XML 文档的解析技术

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

2.2.1 DOM

  • DOM 是基于 XML 的树结构来完成解析的
  • DOM 解析 XML 文档时,会根据读取的文档,构建一个驻留内存的树结构
  • 然后就可以使用 DOM API 来操作这个数结构
  • 因为整个文档的树结构是驻留在内存中的,所以非常方便各种操作
  • 支持删除、修改、重新排列等
  • 但 DOM 解析却是比较消耗资源的

2.2.2 SAX

  • SAX 是基于事件的解析,为了解决 DOM 解析的资源消耗而出现的
  • SAX 解析不用实现调用整个文档,所以占用资源少、内存消耗小
  • 一般在解析数据量较大的 XML 文档时会采用 SAX 方式

2.2.3 JDOM

  • DOM 是不针对语言的,而 JDOM 是针对 Java 的特定文档模型
  • 简化了与 XML 的交互并且比使用 DOM 更快
  • JDOM 仅使用具体类而不使用接口,这在某些方面简化了 API
  • JDOM 的优势在于 "使用20%的精力解决80%的Java/XML问题"

2.2.4 DOM4J

  • DOM4J 是一个非常优秀的 Java XML API,具有性能优异、功能强大和易用的特点。

2.3 使用 DOM 读取 XML 数据

2.3.1 DOM概念

DOM 是 Document Object Model 的简称,即文档对象模型

DOM 把 XML 文件映射成一颗倒挂的"树"

以根元素为节点,每个节点都以对象形式存在

  • 创建文件 book.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<book>
    <title>三国演义</title>
    <author>罗贯中</author>
    <price>30元</price>
</book>
  • book.xml 文档对应的 DOM 树结构:

根元素book 元素:title 元素:author 元素:price 文本:三国演义 文本:罗贯中 文本:30元

2.3.2 使用 DOM 读取手机信息

  • org.w3c.dom:W3C 推荐的用于使用 DOM 解析 XML 文档的接口
  • org.xml.sax:用于使用 SAX 解析 XML 文档的接口。
  • javax.xml.parsers:解析器工厂工具,获得并配置特殊的分析器。
    1. 创建解析器工厂对象,即 DocumentBuilderFactory 对象。、
    2. 由解析器工厂对象创建解析器对象,即 DomentBuilder 对象。
    3. 由解析器对象对指定的 XML 文件进行解析,构建相应的 DOM 树,创建 Document 对象。
    4. 以 Document 对象为起点对 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>
java 复制代码
   //得到 DOM 解析器的工厂实例
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        //从 DOM 工厂获得 DOM 解析器
        DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
        //解析 XML 文档,得到一个 Document 对象,即 DOM 树
        Document document = documentBuilder.parse("src/main/java/CH02XML/sumUP/bookInfo.xml");
        //得到所有 Brand 节点列表信息
        NodeList brandList = document.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++) {
                if (types.item(j).getNodeType() == 1) {
                    Element typeElement = ((Element) types.item(j));
                    String type = typeElement.getAttribute("name");
                    System.out.println("手机:" + attrValue + type);
                }
            }
        }
  1. Node对象

Node 对象是 DOM 结构中最基本的对象,代表了文档树中的一个抽象节点。

  • getChildNodes():返回包含此节点所有的子节点的 NodeList。
  • getFirstChild():如果节点存在子节点,则返回第一个子节点。
  • getLastChild():如果节点存在子节点,则返回最后一个子节点。
  • getNextSibling():返回在 DOM 树中这个节点的下一个兄弟节点。
  • getPreviousSibling():返回在 DOM 树中这个节点的上一个兄弟节点。
  • getNodeName():返回节点的名称。
  • getNodeValue():返回节点的值。
  • getNodeType():返回节点的类型。
  1. NodeList 对象

NodeList 对象是指包含了一个或多个节点(Node)的列表。

可以简单地把它看成一个 Node 数组,也可以通过方法来获得列表中的元素,

  • NodeList 对象的常用方法:

    • getLength():返回列表的长度。

    • item(int index):返回指定位置的 Node 对象。

  1. Document 对象

Document 对象代表整个 XML 文档,

所有其他的 Node 都以一定的顺序包含在 Document 对象之内

排列成一个树状结构,可以通过遍历这颗"树"来得到 XML 文档的所有内容。

它也是对XML文档进行操作的起点。

  • Docuemnt 对象方法如下
    • getElementsByTagName(String name):返回一个 NodeList 对象,它包含了所有给定标签的标签。
    • getDocumentElement():返回一个代表这个 DOM 树的根节点的 Element 对象,也就是代表 XML 文档根元素的对象。
  1. Element 对象

Element 对象代表 XML 文档中的标签元素,继承自 Node,也是 Node 最主要的子对象,也就是代表 XML 文档根元素的对象。

  • 方法如下:
    • getAttribute(String attributename):返回标签中给定属性名称的属性的值。
    • getElementsByTagName(String name):返回具有给定标签名称的所有后代 Element 的 NodeList。

注意:

  1. 使用 Element 的 getElementsByTagName(String name),返回的 NodeList 就是所期待的对象,然后使用 item() 方法提取。
  2. 调用 Node 的getChildNodes() 方法得到 NodeList 对象,每次通过 item() 方法提取 Node 对象后判断 node.getNodeType()==Node.ELEMENT_NODE,即判断是否是元素节点,如果为 true,则是

2.4 使用 DOM4J 解析 XML

2.4.1 DOM4J API 概述

  • 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 节点中产生的一个滤镜或谓词(Predicate)的行为。
  • ProcessingInstruction:定义 XML 处理指令。
  • Text:定义 XML 文本节点。
  • Visitor:用于实现 Visitor 模式。
  • Xpath:通过分析一个字符提供了一个 XPath 表达式。

2.4.2 使用 DOM4J 操作 XML 数据

要使用 DOM4J 读写 XML 文档,需要先下载 dom4j 的 jar 包,在 https://dom4j.github.io 下载后将相应的 jar 包加入工程就可以使用了,

  1. Document 对象相关

    • 读写XML文件,获得 Document 对象。
    java 复制代码
    SAXReader reader=new SAXReader();
    Document document=reader.read(new File("input.xml"));
  2. 节点相关

    1. 获取文档的根元素
    java 复制代码
    Element rootElm=document.getRootElement();
    1. 取得某节点的单个子节点。
    java 复制代码
    Element memberElm=rootElm.element("member");//member是节点名
    1. 取得节点的文字
    java 复制代码
    String text=memberElm.getText();
    1. 取得某节点下名为 "member" 的所有子节点并进行遍历。
    java 复制代码
    List nodes=rootElm.elements("member");
    for(Iterator it=nodes.iterator(); it.hasNext();){
        ELement elm=(Element) it.next();
    }
    1. 在某节点下添加子节点。newMemberElm 是某个已存在的节点。
    java 复制代码
    Element ageElm=newMemberElm.addElement("age");
    1. 设置节点文字。
    jaba 复制代码
    ageElm.setText("29");
    1. 删除某节点
    java 复制代码
    parentElm.remove(childElm);//childEle 是待删除的节点,parentElm 是其父节点
  3. 属性相关

    1. 取得某节点下的某属性。
    java 复制代码
    Element root=document.getRootElement();
    Attribute attribute=root.attribute("size");//size 属性名
    1. 取得属性的值
    java 复制代码
    String text=attribute.Text();
    1. 遍历节点的所有属性。
    java 复制代码
    Element root=document.getRootElement();
    for(Iterator it=root.attributeIterator();it.hasNext()){
        Attribute attribute=(Attribute)it.next();
        String text=attribute.getText();
        System.out.println(texxt);
    }
    1. 为其节点添加属性。
    java 复制代码
    newMemberElm.addAttribute("name","learningdom4j");
    1. 设置属性的值。
    java 复制代码
    Attribute attribute=root.attribute("name");
    attribute.setText("learningdom4j");
    1. 删除某属性
    java 复制代码
    Attribute attribute=root.attribute("size");
    root.remove(attribute);
  4. 将文档写入 XML 文件

    1. 文档中全为英文,不设置编码格式,直接写入
    java 复制代码
    XMLWriter writer=new XMLWriter(new FileWriter("output.xml"));
    writer.write(document);
    writer.close();
    1. 文档中含有中文,设置编码格式在写入。
    java 复制代码
    OutputFormat format=OutputFormat.createPrettyPrint();
    format.setEncoding("GBK"); //指定 XML 编码
    XMLWriter writer=new XMLWriter(new FileWriter("output.xml"));
    writer.write(document);
    writer.close();

将文档写入 XML 文件*

  1. 文档中全为英文,不设置编码格式,直接写入
java 复制代码
XMLWriter writer=new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
  1. 文档中含有中文,设置编码格式在写入。
java 复制代码
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("GBK"); //指定 XML 编码
XMLWriter writer=new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
相关推荐
纪元A梦24 分钟前
分布式拜占庭容错算法——PBFT算法深度解析
java·分布式·算法
卿着飞翔26 分钟前
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
java·rabbitmq·java-rabbitmq
陈阿土i41 分钟前
SpringAI 1.0.0 正式版——利用Redis存储会话(ChatMemory)
java·redis·ai·springai
安全系统学习1 小时前
【网络安全】Qt免杀样本分析
java·网络·安全·web安全·系统安全
程序猿小D1 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim
SoFlu软件机器人1 小时前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
写bug写bug2 小时前
如何正确地对接口进行防御式编程
java·后端·代码规范
Cyanto2 小时前
Java并发编程面试题
java·开发语言·面试
在未来等你2 小时前
互联网大厂Java求职面试:AI大模型与云原生技术的深度融合
java·云原生·kubernetes·生成式ai·向量数据库·ai大模型·面试场景