二、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();
相关推荐
雷神乐乐8 分钟前
File.separator与File.separatorChar的区别
java·路径分隔符
小刘|12 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
逊嘘31 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
morris13138 分钟前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
龙哥说跨境1 小时前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员1 小时前
java导出word文件(手绘)
java·开发语言·word
ZHOUPUYU1 小时前
IntelliJ IDEA超详细下载安装教程(附安装包)
java·ide·intellij-idea
stewie61 小时前
在IDEA中使用Git
java·git
Elaine2023911 小时前
06 网络编程基础
java·网络