XML学习

Sl0th Lv4

XML

简介

XML 指可扩展标记语言(EXtensible Markup Language),被设计用来传输和存储数据 可以用在配置文件中、在网络中传输

HTML 被设计用来显示数据

  • XML 是一种标记语言,很类似 HTML,是对 HTML 的补充

  • XML 的设计宗旨是传输数据,而非显示数据

  • XML 标签没有被预定义。您需要自行定义标签。(通过 XML 可以发明自己的标签)

  • XML 被设计为具有自我描述性

  • XML 是 W3C 的推荐标准

  • XML 仅仅是纯文本

  • XML 独立于硬件、软件以及应用程序

树结构

一个文档实例(John 给 George 的一张便签)

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="ISO-8859-1"?> <!--XML 声明。它定义 XML 的版本 (1.0) 和所使用的编码 (ISO-8859-1 = Latin-1/西欧字符集)-->
<note> <!--根元素-->
<!--4 行描述根的 4 个子元素(to, from, heading 以及 body)-->
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

所有的XML元素都必须有一个关闭标签 e.g.

也可以使用自闭合标签 e.g. <br/>

组成部分

⚠️注意:xml第一行必须定义为文档声明

格式:

属性列表:

  • version:版本号,必须的属性
  • encoding:编码方式。告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1 若存中文,用gbk
  • standalone:是否独立
    • 取值:
      * yes:不依赖其他文件
      • no:依赖其他文件
  1. 指令(了解):结合css的w
    • (给当前xml加样式)
  2. 标签:标签名称自定义的
    * 规则:
    * 名称可以包含字母、数字以及其他的字符
    * 名称不能以数字或者标点符号开始
    * 名称不能以字母 xml(或者 XML、Xml 等等)开始
    * 名称不能包含空格
  3. 属性:
    id属性值唯一
  4. 文本:
    * CDATA区:在该区域中的数据会被原样展示
    * 格式: (原样展示也就意味着不用实体代替特殊字符)

XML 文档形成一种树结构

XML 文档必须包含根元素。该元素是所有其他元素的父元素。

XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。

1
2
3
4
5
<root>
<child>
<subchild>.....</subchild>
</child>
</root>

所有元素都可以有子元素

语法

大小写敏感

1
2
<Message>这是错误的。</message>
<message>这是正确的。</message>

正确嵌套

1
2
<b><i>错误</b></i>
<b><i>正确</i></b>

必须有一个根元素(子元素间可以并列)

1
2
3
4
5
6
7
8
<root>
<child category="COOKING">
<subchild>.....</subchild>
</child>
<child category="WEB">
<subchild>.....</subchild>
</child>
</root>

属性值要加引号

单双都可以

1
2
3
4
<note date="08/08/2008">
<to>George</to>
<from>John</from>
</note>

实体引用

特殊符号转义

&lt; < 小于
&gt; > 大于
&amp; & 和号
&apos; 单引号
&quot; 引号
1
2
<message>if salary < 1000 then</message>
<message>if salary &lt; 1000 then</message>

在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。

注释

使用<!----> (都是两个短横杠)

1
<!-- This is a comment -->  

保留空格

在 XML 中,文档中的空格不会被删节。

HTML 会把多个连续的空格字符裁减(合并)为一个:

1
2
HTML:	Hello           my name is David.
输出: Hello my name is David.

LF存储换行

在 Windows 应用程序中,换行通常以一对字符来存储:回车符 (CR) 和换行符 (LF)。这对字符与打字机设置新行的动作有相似之处。在 Unix 应用程序中,新行以 LF 字符存储。而 Macintosh 应用程序使用 CR 来存储新行。

元素

XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。

命名规则

  • 名称可以含字母、数字以及其他的字符
  • 名称不能以数字或者标点符号开始
  • 名称不能以字符 “xml”(或者 XML、Xml)开始
  • 名称不能包含空格
  • 可使用任何名称,没有保留的字词

避免 “-“ 字符。如果您按照这样的方式进行命名:”first-name”,一些软件会认为你需要提取第一个单词。

避免 “.” 字符。如果您按照这样的方式进行命名:”first.name”,一些软件会认为 “name” 是对象 “first” 的属性。

避免 “:” 字符。冒号会被转换为命名空间来使用。

XML 文档经常有一个对应的数据库,其中的字段会对应 XML 文档中的元素。有一个实用的经验,即使用数据库的名称规则来命名 XML 文档中的元素。

属性

属性 (Attribute) 提供关于元素的额外(附加)信息。

属性值必须被引号包围,不过单引号和双引号均可使用。比如一个人的性别,person 标签可以这样写:

1
2
<person sex="female">
<person sex='female'>

如果属性值本身包含双引号,那么有必要使用单引号包围它,就像这个例子:

1
2
3
<gangster name='George "Shotgun" Ziegler'>
<!--或者使用实体引用-->
<gangster name="George &quot;Shotgun&quot; Ziegler">

属性与元素的使用没有规定,可以按照自己喜欢的方式

1
2
3
4
5
6
7
8
9
10
<person sex="female">
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>

<person>
<sex>female</sex>
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>

因使用属性而引起的一些问题:

  • 属性无法包含多重的值(元素可以)
  • 属性无法描述树结构(元素可以)
  • 属性不易扩展(为未来的变化)
  • 属性难以阅读和维护

元数据(有关数据的数据)应当存储为属性,而数据本身应当存储为元素

有时候会向元素分配 ID 引用。这些 ID 索引可用于标识 XML 元素,它起作用的方式与 HTML 中 ID 属性是一样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<messages>
<note id="501">
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
<note id="502">
<to>John</to>
<from>George</from>
<heading>Re: Reminder</heading>
<body>I will not</body>
</note>
</messages>

XML验证

拥有正确语法的 XML 被称为“形式良好”的 XML。

通过 DTD 验证的 XML 是“合法”的 XML。

XML Schema

W3C 支持一种基于 XML 的 DTD 代替者,它名为 XML Schema:

1
2
3
4
5
6
7
8
9
10
11
12
<xs:element name="note">

<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>

</xs:element>

XML DTD

DTD 的作用是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构:

1
2
3
4
5
6
7
<!DOCTYPE note [ <!--DOCTYPE 声明是对外部 DTD 文件的引用-->
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>

XML CSS

XML可以连接到CSS文件并被其格式化,呈现在网页上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/css" href="cd_catalog.css"?> <!--把这个XML文件链接到CSS文件-->
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
.
.
.
.
</CATALOG>

使用 CSS 格式化 XML 不是常用的方法,更不能代表 XML 文档样式化的未来。W3C 推荐使用 XSLT

XML XSLT

XSLT 是首选的 XML 样式表语言。

XSLT (eXtensible Stylesheet Language Transformations) 远比 CSS 更加完善。

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="simple.xsl"?> <!--把这个XML文件链接到XSL文件-->
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>
two of our famous Belgian Waffles
</description>
<calories>650</calories>
</food>
</breakfast_menu>

在使用 XSLT 来转换 XML 时,不同的浏览器可能会产生不同结果。为了减少这种问题,可以在服务器上进行 XSLT 转换。

DOM 将 XML 文档作为一个树形结构,而树叶被定义为节点

以书店文档为例

image-20220427143813504
image-20220427143813504

XML约束

  • 约束:规定xml文档的书写规则

    • 作为框架的使用者(程序员):

      1. 能够在xml中引入约束文档
      2. 能够简单的读懂约束文档
    • 分类:

      1. DTD:一种简单的约束技术
      2. Schema:一种复杂的约束技术

DTD:

  • 引入dtd文档到xml文档中
    • 内部dtd:将约束规则定义在xml文档中
    • 外部dtd:将约束的规则定义在外部的dtd文件中
      • 本地:
      • 网络:

Schema:

可以自定义类型,给标签内容更多的规定

  • 引入:
    1. 填写xml文档的根元素
    2. 引入xsi命名空间(xsi标准命名空间,有多种取值 分别对应不同版本). xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance
    3. 为每个命名空间指定具体的schema文件 两两一对 xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
    4. 为每一个xsd约束声明一个前缀,作为标识 xmlns=”http://www.itcast.cn/xml “ (xmlns定义默认命名空间,只引一个约束文档时,可以不加前缀,为空前缀,可以直接使用标签,默认所有标签都用这个文档)
      • 加前缀版(自定义命名空间,给命名空间取别名,其赋值必须是个命名空间文件 必须在xsi命名空间内指定其对应的schema文件):xmlns:a=”http://www.itcast.cn/xml1 “ 使用该约束文档的标签都要加前缀 如<a:age></a:age>

根标签内引入

1
2
3
<students   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/xml"
xsi:schemaLocation="http://www.itcast.cn/xml student.xsd">

image-20220727204100444
image-20220727204100444

XML解析

解析:操作xml文档,将文档中的数据读取到内存中

  • 操作xml文档

    1. 解析(读取):将文档中的数据读取到内存中
    2. 写入:将内存中的数据保存到xml文档中。持久化的存储
  • 解析xml的方式:

    1. DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树

    image-20220727204321916
    image-20220727204321916

    • 优点:操作方便,可以对文档进行CRUD的所有操作
    • 缺点:占内存
    1. SAX:逐行读取(自动释放上一行),基于事件驱动的。
    • 优点:不占内存。
    • 缺点:只能读取,不能增删改

xml常见的解析器:

​ 1. JAXP:sun公司提供的解析器,支持dom和sax两种思想
​ 2. DOM4J:一款非常优秀的解析器
​ 3. Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
​ 4. PULL:Android操作系统内置的解析器,sax方式的。

Jsoup

jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

  • 快速入门:

    • 步骤:
      1. 导入jar包
      2. 获取Document对象
      3. 获取对应的标签Element对象
      4. 获取数据
  • 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //获取Document对象,根据xml文档获取
    //获取student.xml的path
    String path= JsoupDemo1.class.getClassLoader().getResource("student.xml").toURI().getPath();
    //解析xml文档,加载文档进内存,获取dom树-->Document
    Document document = Jsoup.parse(new File(path), "utf-8");
    //获取元素对象 Element
    Elements elements = document.getElementsByTag("name");//Elements是ArrayList<Element>
    System.out.println(elements.size());
    //获取第一个name的Element对象
    Element element = elements.get(0);
    //获取数据
    String text = element.text();
    System.out.println(text);

    路径中有中文或空格时,要先toURI再getPath

  • 对象的使用:

    1. Jsoup:工具类,可以解析html或xml文档,返回Document
      • parse:解析html或xml文档,返回Document
        • parse(File in, String charsetName):解析xml或html文件的。
        • parse(String html):解析xml或html字符串
        • parse(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象
    2. Document:文档对象。代表内存中的dom树
      • 获取Element对象
        • getElementById(String id):根据id属性值获取唯一的element对象
        • getElementsByTag(String tagName):根据标签名称获取元素对象集合
        • getElementsByAttribute(String key):根据属性名称获取元素对象集合
        • getElementsByAttributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合
    3. Elements:元素Element对象的集合。可以当做 ArrayList来使用
    4. Element:元素对象
      1. 获取子元素对象

        • getElementById(String id):根据id属性值获取唯一的element对象
        • getElementsByTag(String tagName):根据标签名称获取元素对象集合
        • getElementsByAttribute(String key):根据属性名称获取元素对象集合
        • getElementsByAttributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合
      2. 获取属性值

        • String attr(String key):根据属性名称(大小写不敏感)获取属性值
      3. 获取文本内容

        • String text():获取文本内容(所有子标签的纯文本内容拼接,不包含标签名及<>)
        • String html():获取标签体的所有内容(包括子标签的字符串内容,包含标签名及<>)
    5. Node:节点对象
      • 是Document和Element的父类
  • 快捷查询方式:

    1. selector:选择器

      • 使用的方法:Elements select(String cssQuery)

        • 语法:参考Selector类中定义的语法
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        //选择器查询
        String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").toURI().getPath();
        Document document = Jsoup.parse(new File(path), "utf-8");
        //获取name标签
        Elements elements = document.select("name");
        System.out.println(elements);
        //获取id="itcast"的元素
        Elements elements1 = document.select("#itcast");
        System.out.println(elements1);
        System.out.println("-------");
        //获取student标签下number="heima_0001的age子标签
        Elements elements2 = document.select("student[number='heima_0001']");
        System.out.println(elements2);
        Elements elements3 = document.select("student[number='heima_0001'] > age");
        //得到age
        System.out.println(elements3);
    2. XPath:XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言

      • 使用Jsoup的Xpath需要额外导入jar包。
      • 查询w3cshool参考手册,使用xpath的语法完成查询
      • 代码:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").toURI().getPath();
      Document document = Jsoup.parse(new File(path), "utf-8");
      //根据document对象,创建JXDocument对象
      JXDocument jxDocument=new JXDocument(document);
      //结合Xpath语法查询
      List<JXNode> jxNodes = jxDocument.selN("//student"); // '//'表示当前节点
      for (JXNode jxNode: jxNodes) {
      System.out.println(jxNode);
      }
      //查询所有student标签下的name标签
      List<JXNode> jxNodes1 = jxDocument.selN("//student/name");
      for (JXNode j: jxNodes1) {
      System.out.println(j);
      }
      //查询student标签下带有id属性的name标签
      List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@id]");
      for (JXNode jxNode : jxNodes3) {
      System.out.println(jxNode);
      }
      //查询student标签下带有id属性的name标签 并且id属性值为itcast
      List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id='itcast']");
      for (JXNode jxNode : jxNodes4) {
      System.out.println(jxNode);
      }
  • 标题: XML学习
  • 作者: Sl0th
  • 创建于 : 2022-04-20 00:00:55
  • 更新于 : 2024-07-04 00:12:34
  • 链接: http://sl0th.top/2022/04/20/XML学习/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论