XML 基础
第1章 XML 概述
1.1 引入
一段标注你的XML数据格式:
<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推荐的数据传输格式
XML和HTML的区别:
- HTML标签不能自定义;XML标签只能自定义
- HTML语法要求不严格;XML语法要求极其严格,必须是成对标签
- HTML用来展示数据;XML用来传输和存储数据
第2章 XML 的基本语法
2.1 语法规则
- XML必须有根节点:根节点就是其他所有节点的父级节点
- XML头声明:不强制要求,可有可无,但是建议写
- 所有XML元素都必须是成对标签
- 标签名大小写敏感(区分大小写)
- 标签不能交叉
- 注释
- 特殊字符需要转义为实体字符
在XML中需要转义的字符有:
实体字符 | 符号 | 含义 |
---|---|---|
< | < | less than |
> | > | greater than |
& | & | ampersand |
' | ‘ | apostrophe |
" | “ | quotation mark |
2.2 元素属性
属性就是表示标签自身的一些额外信息
属性规则:
一个标签可以有多个属性,属性的值必须使用引号引起来;
命名规则:数字字母下划线,数字不能开头;
在解析XML数据时,属性会带来额外的解析代码(多了一步,比较麻烦)
2.3 CDATA
语法:
<![CDATA[...不解析的内容....]]>
注意:特殊字符较少时,使用实体替换,较多时使用CDATA
第3章 DTD
3.1 DTD简介
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
内部的 DOCTYPE 声明
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE root-element [element-declarations]>
example:
<?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 定义中:
<!DOCTYPE root-element SYSTEM "filename">
这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD:
<?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” 文件:
<!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:
<body>some text</body>
<message>some text</message>
在一个 DTD 中,元素通过元素声明来进行声明。
<!ELEMENT element-name category>
或
<!ELEMENT element-name (element-content)>
example:
空元素
<!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:
<img src="computer.gif" />
在 DTD 中,属性通过 ATTLIST 声明来进行声明。
<!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 | 属性值是固定的 |
默认属性值
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">
合法的 XML:
<square width="100" />
“square” 被定义为带有 CDATA 类型的 “width” 属性的空元素。如果宽度没有被设定,其默认值为0 。
#REQUIRED
<!ATTLIST element-name attribute-name attribute-type #REQUIRED>
example:
<!ATTLIST person number CDATA #REQUIRED>
合法的 XML:
<person number="5677" />
非法的 XML:
<person />
假如您没有默认值选项,但是仍然希望强制作者提交属性的话,请使用关键词 #REQUIRED。
#IMPLIED
<!ATTLIST element-name attribute-name attribute-type #IMPLIED>
example:
<!ATTLIST contact fax CDATA #IMPLIED>
合法的 XML:
<contact fax="555-667788" />
合法的 XML:
<contact />
假如您不希望强制作者包含属性,并且您没有默认值选项的话,请使用关键词 #IMPLIED。
#FIXED
<!ATTLIST element-name attribute-name attribute-type #FIXED "value">
example:
<!ATTLIST sender company CDATA #FIXED "Microsoft">
合法的 XML:
<sender company="Microsoft" />
非法的 XML:
<sender company="W3Schools" />
如果您希望属性拥有固定的值,并不允许作者改变这个值,请使用 #FIXED 关键词。如果作者使用了不同的值,XML 解析器会返回错误。
列举属性值
<!ATTLIST element-name attribute-name (en1|en2|..) default-value>
example:
<!ATTLIST payment type (check|cash) "cash">
XML 例子:
<payment type="check" />
或
<payment type="cash" />
如果您希望属性值为一系列固定的合法值之一,请使用列举属性值。
实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
- 实体引用是对实体的引用。
- 实体可在内部或外部进行声明。
一个内部实体声明
<!ENTITY entity-name "entity-value">
example:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
XML 实例:
<author>&writer;©right;</author>
注意: 一个实体由三部分构成: 一个和号 &
, 一个实体名称, 以及一个分号 ;
。
一个外部实体声明
<!ENTITY entity-name SYSTEM "URI/URL">
example:
<!ENTITY writer SYSTEM "http://www.runoob.com/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.runoob.com/entities.dtd">
XML example:
<author>&writer;©right;</author>
PCDATA
PCDATA 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &
、<
或者 >
字符;需要使用 &
、<
以及 >
实体来分别替换它们。
CDATA
CDATA 的意思是字符数据(character data)。
CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
第4章 使用PHP解析 XML
SimpleXML 是 PHP 5 中的新特性。
SimpleXML 扩展提供了一种获取 XML 元素的名称和文本的简单方式。
4.1 XML解析原理
PHP解析XML共分为3步:
- 读取XML文档到内存
- 形成DOM树
- 由DOM树生成对象并返回
4.2 simpleXML类库
<?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;
#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>
返回结果:
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数据
<?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增加节点
<?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 使用以及语法
<?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);