XML基础
John_Frod Lv4

XML 基础


第1章 XML 概述

1.1 引入

一段标注你的XML数据格式:

1
2
3
4
5
6
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

XML数据格式最主要的功能就是数据传输


XML数据格式主要的用途又有哪些?

  • 程序之间的数据传输通讯

  • 配置文件 config.xml

  • 存储数据,充当小型数据库 data.xml


规范数据格式,使数据具有结构性,易读易处理


1.2 什么是XML

XML指的是,可扩展性标记语言

XML被发明的目的是传输和存储数据,而不是展示数据

XML的标签必须自定义,但是在写标签名的时候一定要有含义

XML是W3C推荐的数据传输格式


image-20210412095414134

image-20210412095446132


XML和HTML的区别:

  • HTML标签不能自定义;XML标签只能自定义
  • HTML语法要求不严格;XML语法要求极其严格,必须是成对标签
  • HTML用来展示数据;XML用来传输和存储数据

第2章 XML 的基本语法

2.1 语法规则

  • XML必须有根节点:根节点就是其他所有节点的父级节点

image-20210412100718124

  • XML头声明:不强制要求,可有可无,但是建议写

image-20210412101036572

  • 所有XML元素都必须是成对标签

image-20210412101403328

  • 标签名大小写敏感(区分大小写)

  • 标签不能交叉

image-20210412101804082

  • 注释

image-20210412101926173

image-20210412102030263

  • 特殊字符需要转义为实体字符

image-20210412102529042

image-20210412102548578

在XML中需要转义的字符有:

实体字符 符号 含义
&lt; < less than
&gt; > greater than
&amp; & ampersand
&apos; apostrophe
&quot; quotation mark

2.2 元素属性

属性就是表示标签自身的一些额外信息

image-20210412104107448

属性规则:

一个标签可以有多个属性,属性的值必须使用引号引起来;

命名规则:数字字母下划线,数字不能开头;

在解析XML数据时,属性会带来额外的解析代码(多了一步,比较麻烦)


2.3 CDATA

语法:

1
<![CDATA[...不解析的内容....]]>

image-20210412114050036

image-20210412114059602

注意:特殊字符较少时,使用实体替换,较多时使用CDATA


第3章 DTD

3.1 DTD简介

DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。

DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

内部的 DOCTYPE 声明

假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:

1
<!DOCTYPE root-element [element-declarations]>

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>
  • DOCTYPE note (第二行)定义此文档是 note 类型的文档。
  • !ELEMENT note (第三行)定义 note 元素有四个元素:”to、from、heading,、body”
  • !ELEMENT to (第四行)定义 to 元素为 “#PCDATA” 类型
  • !ELEMENT from (第五行)定义 from 元素为 “#PCDATA” 类型
  • !ELEMENT heading (第六行)定义 heading 元素为 “#PCDATA” 类型
  • !ELEMENT body (第七行)定义 body 元素为 “#PCDATA” 类型

外部文档声明

假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

1
<!DOCTYPE root-element SYSTEM "filename">

这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD:

1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

这是包含 DTD 的 “note.dtd” 文件:

1
2
3
4
5
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

3.2 DTD构建模块

所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:

元素

元素是 XML 以及 HTML 文档的主要构建模块

HTML 元素的例子是 “body” 和 “table”。XML 元素的例子是 “note” 和 “message” 。元素可包含文本、其他元素或者是空的。空的 HTML 元素的例子是 “hr”、”br” 以及 “img”。

example:

1
2
<body>some text</body>
<message>some text</message>

在一个 DTD 中,元素通过元素声明来进行声明。

1
2
3
<!ELEMENT element-name category>

<!ELEMENT element-name (element-content)>

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
空元素
<!ELEMENT element-name EMPTY>
只有 PCDATA 的元素
<!ELEMENT element-name (#PCDATA)>
带有任何内容的元素
<!ELEMENT element-name ANY>
带有子元素(序列)的元素
<!ELEMENT element-name (child1,child2,...)>
<!ELEMENT child1 (#PCDATA)>
<!ELEMENT child2 (#PCDATA)>
...

声明只出现一次的元素
<!ELEMENT element-name (child-name)>
声明最少出现一次的元素
<!ELEMENT element-name (child-name+)>
声明出现零次或多次的元素
<!ELEMENT element-name (child-name*)>
声明出现零次或一次的元素
<!ELEMENT element-name (child-name?)>
声明"非.../即..."类型的内容
<!ELEMENT note (to,from,header,(message|body))>
声明混合型的内容
<!ELEMENT note (#PCDATA|to|from|header|message)*>

当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。

属性

属性可提供有关元素的额外信息

属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。

example:

1
<img src="computer.gif" />

在 DTD 中,属性通过 ATTLIST 声明来进行声明。

1
<!ATTLIST element-name attribute-name attribute-type attribute-value>

以下是 属性类型的选项:

类型 描述
CDATA 值为字符数据 (character data)
(en1|en2|..) 此值是枚举列表中的一个值
ID 值为唯一的 id
IDREF 值为另外一个元素的 id
IDREFS 值为其他 id 的列表
NMTOKEN 值为合法的 XML 名称
NMTOKENS 值为合法的 XML 名称的列表
ENTITY 值是一个实体
ENTITIES 值是一个实体列表
NOTATION 此值是符号的名称
xml: 值是一个预定义的 XML 值

默认属性值可使用下列值 :

解释
属性的默认值
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性值是固定的

默认属性值
1
2
3
4
5
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">

合法的 XML:
<square width="100" />

“square” 被定义为带有 CDATA 类型的 “width” 属性的空元素。如果宽度没有被设定,其默认值为0 。

#REQUIRED
1
<!ATTLIST element-name attribute-name attribute-type #REQUIRED>

example:

1
2
3
4
5
6
7
<!ATTLIST person number CDATA #REQUIRED>

合法的 XML:
<person number="5677" />

非法的 XML:
<person />

假如您没有默认值选项,但是仍然希望强制作者提交属性的话,请使用关键词 #REQUIRED。

#IMPLIED
1
<!ATTLIST element-name attribute-name attribute-type #IMPLIED>

example:

1
2
3
4
5
6
7
<!ATTLIST contact fax CDATA #IMPLIED>

合法的 XML:
<contact fax="555-667788" />

合法的 XML:
<contact />

假如您不希望强制作者包含属性,并且您没有默认值选项的话,请使用关键词 #IMPLIED。

#FIXED
1
<!ATTLIST element-name attribute-name attribute-type #FIXED "value">

example:

1
2
3
4
5
6
7
<!ATTLIST sender company CDATA #FIXED "Microsoft">

合法的 XML:
<sender company="Microsoft" />

非法的 XML:
<sender company="W3Schools" />

如果您希望属性拥有固定的值,并不允许作者改变这个值,请使用 #FIXED 关键词。如果作者使用了不同的值,XML 解析器会返回错误。

列举属性值
1
<!ATTLIST element-name attribute-name (en1|en2|..) default-value>

example:

1
2
3
4
5
6
<!ATTLIST payment type (check|cash) "cash">

XML 例子:
<payment type="check" />

<payment type="cash" />

如果您希望属性值为一系列固定的合法值之一,请使用列举属性值。


实体

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。

  • 实体引用是对实体的引用。
  • 实体可在内部或外部进行声明。
一个内部实体声明
1
<!ENTITY entity-name "entity-value">

example:

1
2
3
4
5
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">

XML 实例:
<author>&writer;&copyright;</author>

注意: 一个实体由三部分构成: 一个和号 &, 一个实体名称, 以及一个分号 ;

一个外部实体声明
1
<!ENTITY entity-name SYSTEM "URI/URL">

example:

1
2
3
4
5
<!ENTITY writer SYSTEM "http://www.runoob.com/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.runoob.com/entities.dtd">

XML example:
<author>&writer;&copyright;</author>

PCDATA

PCDATA 的意思是被解析的字符数据(parsed character data)。

可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。

PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。

文本中的标签会被当作标记来处理,而实体会被展开。

不过,被解析的字符数据不应当包含任何 &< 或者 > 字符;需要使用 &amp;&lt; 以及 &gt; 实体来分别替换它们。


CDATA

CDATA 的意思是字符数据(character data)。

CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。


第4章 使用PHP解析 XML

SimpleXML 是 PHP 5 中的新特性。

SimpleXML 扩展提供了一种获取 XML 元素的名称和文本的简单方式。

4.1 XML解析原理

PHP解析XML共分为3步:

  1. 读取XML文档到内存
  2. 形成DOM树
  3. 由DOM树生成对象并返回

4.2 simpleXML类库

1
2
3
4
5
6
7
8
9
10
<?php
//simplexml_load_file解析XML文档,返回PHP对象
$x = simplexml_load_file('3.1.xml');

#或者
$s = file_get_contents('3.1.xml'); //返回字符串
$x = simplexml_load_string($s); //参数接收XML内容,而不是文件

var_dump($x);
echo $x->man[0]->name;
1
2
3
4
5
6
7
8
9
10
11
12
#3.1.xml
<?xml version="1.0" encoding="utf-8" ?>
<root>
<man>
<name>金星</name>
<age>36</age>
</man>
<man>
<name>太白</name>
<age>46</age>
</man>
</root>

返回结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
object(SimpleXMLElement)#1 (1) {		#调用simplexml_load_file函数,解析XML生成的对象
["man"]=> #PHP将XML节点以属性的形式存放
array(2) { #内容如果有多条,以数组的形式存放
[0]=>
object(SimpleXMLElement)#2 (2) {
["name"]=> #数组的值就是解析后的节点名字和内容,以对象属性的形式存放
string(6) "金星"
["age"]=>
string(2) "36"
}
[1]=>
object(SimpleXMLElement)#3 (2) {
["name"]=>
string(6) "太白"
["age"]=>
string(2) "46"
}
}
}
金星

4.3 遍历XML数据

1
2
3
4
5
6
7
8
9
10
11
12
<?php
//simplexml_load_file解析XML文档,返回PHP对象
$x = simplexml_load_file('3.1.xml');

foreach ($x->man as $v){
echo $v->name;
}
#或者
$c = count($x->man);
for($i=0;$i<$c;$i++){
echo $x->man[$i]->name;
}

4.4 使用SimpleXML增加节点

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
//simplexml_load_file解析XML文档,返回PHP对象
$x = simplexml_load_file('3.1.xml');

//对象中的addChild方法创建节点
$man = $x->addChild('man');
//对象中的addChild方法创建节点,并给创建后的节点添加内容
$man->addChild('name','玉帝');
$man->addChild('age','999');

var_dump($x);
//将添加后的对象重新解析成XML文档,写入文件
$x->asXML('3.1.xml');

第5章 Xpath

5.1 概述

XPath 是一门在 XML 文档中查找信息的语言。

用来在XML文档中对元素及属性进行遍历;


5.2 使用以及语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
//simplexml_load_file解析XML文档,返回PHP对象
$x = simplexml_load_file('newXML.xml');

//xpath 查找后仍然返回数组,数组中的值仍然为对象

//路径查找
$d = $x->xpath('/root/man/name'); //参数为路径,以 / 开始的为绝对路径查找
$d = $x->xpath('//name'); //参数为路径,以 / 开始的为绝对路径查找
$d = $x->xpath('//man/*'); //使用*匹配所有节点

//条件查找
$d = $x->xpath('//man[age<120]'); //使用*匹配所有节点
$d = $x->xpath('//man[last()]');
$d = $x->xpath('//man[@msg]'); //属性查找


var_dump($d);
  • Post title:XML基础
  • Post author:John_Frod
  • Create time:2021-04-14 09:17:18
  • Post link:https://keep.xpoet.cn/2021/04/14/XML基础/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.