一、XML语法
1、XML文档的构造
序言 + 数据
序言表明了XML的版本,并且有时也指明文本编码:
<?xml version="1.1" encoding="utf-8">
XML文档的主要部分是其内容本身。在这部分,如一个HTML网页一般,以根元素开始和结束。每个XML文档只能有一个根元素。
根元素之内是更多嵌套的元素。每个元素包含一个开始标签、元素数据和一个结束标签:
<tag>data</tag>
示例:
<?xml version="1.1" encoding="utf-8"?> <!-- store.xml --> <!DOCTYPE store SYSTEM "syatem.dtd"> <store> <product> <name>T-Shirt</name> <size>XL</size> </product> <product> <name>Sweater</name> <size>L</size> <picture filename="sweater.jpg" /> </product> </store>
XML元素应遵循的规则:
- 对于每一个都必须有对应的
- 元素可以嵌套,但是不可相互交叉嵌套,例如:Hello,在XML中是不允许的。
- 标签名区分大小写。可以使用字母、数字及其他一些字符作为标签名,但是标签名不可有空格或者以“xml”开头,只能以字母或下划线开头。
2、属性、空元素和实体
与HTML相似,XML元素可以有属性:
<tag attribute_name="value">data</tag>
XML元素可以有无限多数量的属性;但是每一个属性必须有一个值,不可以这样做
<p caption>data</p>
既可以使用单引号也可以使用双引号括起属性值。但是必须使用引号,引号格式要一致。
属性常与空元素一起使用,空元素是不包含任何数据的元素。例如HTML中的就是一个空元素。与XHTML要求空元素最后 一定要有一个空格及斜线一样,XML也如此要求:
<tag attribute="value" />
在XML数据中,不能使用某些字符,因为它们可能会引起冲突,而代以一种组合来表示这些字符,即为可能产生问题的字符的实体版本。实体总是以一个&开始,以;结束。
实体字符 含义 &
& <
< >
> '
‘ "
“
3、DTD
XML文件主要是用来包含数据。架构是XML文档内容的向导。架构是可选的,但是一旦条件允许,就可以确保XML数据是有效的。
架构可以使用两种方法表示:
- DTD,一个文档类型定义(Document Type Definition)
- XML架构(允许将XML数据映射到具体类型,而不是DTD中的一般数据类别)
3.1 包含DTD
要将DTD与一个XML文件结合起来,在序言之后、数据之前列举放置一个引用行:
<? xml version="1.1" encoding="utf-8"?>
<!DOCTYPE rootelement [definition]>
如果在单独的文件中定义许可的元素,文件类型声明会形如:
<!DOCTYPE rootelement SYSTEM "/path/to/filename.dtd">
使用外部DTD的好处:
1.信息只需要传送一次,不管传送多少个XML文档
2.外部文档更易编辑
3.2 定义元素
DTD定义了你的标记语言中使用的所有元素和属性。其定义元素的语法为:
<!ELEMNT name TYPE>
其中name是标签的名字,它将包含类型为TYPE的内容。
类型 | 关联数据 |
---|---|
(#PCDATA) | 一般文本(特指已解析字符数据) |
(#CDATA) | 一般文本(特指未解析字符数据) |
EMPTY | 无 |
ANY | 任何数据 |
如果将这些规则应用到前面举得示例XML文档中,可以这样:
<!ELEMENT name (#PCDATA)>
<!ELEMENT size (#PCDATA)>
<!ELEMENT picture EMPTY>
最后一个元素picture,是EMPTY类型,因为它没有内容(它有一个名为filename的属性)。
还有一个元素product,它包含了所有其他元素。
定义product:
<!ELEMENT product (name, size*, picture?)>
声明product元素以name、size、picture的顺序包含了其他三个元素。其中,size元素可以出现零到多次,pictu元素是可选的,但是出现的时候只能出现一次。
符号 | 含义 |
---|---|
? | 可选(0或1次) |
+ | 至少一次 |
* | 0或多次 |
| | 或关系 |
3.3 定义属性
DTD定义元素的属性的语法为:
<!ATTLIST element_name attr_name attr_type attr_description>
attr_name域只是一个简单的文本串,如color或者alignment那样。attr_type指定属性的格式,可能值有:
类型 | 含义 | 示例 |
---|---|---|
CDATA | 字符数据 | 一般文本 |
NMTOKEN | 名字令牌 | 字符串(不包含空白) |
NMTOKENS | 若干名字令牌 | 由空白字符分开(如“Jessica Zoe Sam”) |
还有一种可能取值的枚举列表:
<!ATTLIST element_name attr_name (value1 | value2) "value1">
前面的代码声明element_name有一个属性attr_name,属性的取值有两个可能:value1或者value2,默认value1
属性描述(attr_description)为属性的功能进一步定义。可能的属性描述有:
符号 | 含义 |
---|---|
REQUIRED | 元素必须使用该属性 |
IMPLIED | 该属性是可选的 |
FIXED | 该属性的值不可改变 |
4、XSD
XML架构(XML Schema)是一种用于定义可接受的XML数据的更有力且更复杂的工具。例如,与DTD在元素类型上模糊不清(大多都转换成某种字符数据)相反,XML架构能够要求元素包含整数、字符串、小数、有效的国家代码等。
为避免与通用架构语言混淆,XML架构现在叫做XML架构文档(XML Schema Document, XSD)。
4.1 合并XSD
XSD 是用XML编写的。要想向XML文件中添加XSD,可以使用schema元素(在XML序言之后、数据之前):
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- Schema Information Here --> </xs:schema> <!-- Start XML Data -->
在以xs开头的schema中有一些额外的东西,成为命名空间(namespace)引用,开放的schema标签指明了命名空间定义所在位置。
要使用XSD文档,首先要创建该文件,扩展名为.xsd。要将该XSD文件与XML文档联系起来,需要在XML文档的根标签上引用该XSD文件:
<rootelementxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="somefile.xsd">
第一个属性xmlns指明了该XML架构实例(XML Schema Instance,XSI)的命名空间。xsi:noNamespaceSchemaLocation属性指明XSD文件的路径。
4.2 定义元素
在XSD中使用如下格式定义元素:
<xs:element name="element_name" type="some_type" />
数据类型可以有以下几种预定义类型:
xs:string、 xs:integer、 xs:boolean、 xs:decimal、 xs:data可以使用element标签的属性来定制元素:
1. default属性,声明一个默认值
2. fixed属性,声明元素仅能有一个值
例如:
<xs:element name="edition" type="xs:integer" default="1" />
对于DTD可以限制元素在其上下文中出现的次数,在这通过使用minOccurs与maxOccurs属性来完成:
<xs:element name="size" type="xs:string" minOccurs="1" maxOccurs="10" />
这段代码表明size元素至少要出现1次,但最大10次。那么不含size元素的XML就是非法。
minOccurs与maxOccurs默认值都是1,意味着如果这些元素没有重新声明,对应的元素必须出现且仅能出现一次。
要允许任意次出现,可将minOcurs设为0,maxOccurs设为unboun。
4.3 简单类型与复杂类型
可以使用xs:simpleType和xs:complexType来创建用户定义类型。
简单类型是其他默认类型的变体得来,复杂类型是用户定义类型,为其他类型的组合。
<xs:element name="product">
<xs:complexType>
<xs:sequence>
<!-- Subtypes -->
</xs:sequence>
</xs:compexType>
</xs:element>
定义复杂类型的另一个方法:给它一个name属性,然后在所需之处使用新类型。
4.4 创建属性
使用xs:attribute来声明元素属性,并提供名字与类型:
<xs:attribute name="price" type="xs:decimal" />
示例:
第一个声明的是根元素:collection。它包含一个或多个book元素,book元素类型是接下来定义的bookType。
<xs:element name="collection"> <xs:complexType> <xs:seauence> <xs:element name-"book" type="bookType" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element>
复杂类型bookType:它可以包含以下元素的某一个或者全部(title、author、chapter)。
<xs:complexType name="bookType"> <xs:sequence> <xs:element name="title" type="titleType" /> <xs:element name="author" type="xs:string" minOccurs="1" maxOccurs="unbounded" /> <xs:element name="chapter" type="chapterType" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType>
title元素的titleType类型定义了它可以有一个值和一个edition属性。
<xs:complexType name="titleType"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="edition" type="xs:int" /> </xs:extension> </xs:simpleContent> </xs:complexType>
chapter元素的chapterType类型定义了它可以有一个值(字符串类型,即章节名称)和两个属性:number和page。
<xs:complexType name="chapterType"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="number" type="xs:int" /> <xs:attribute name="page" type="xs:int" /> </xs:extension> </xs:simpleContent> </xs:complexType>
二、PHP解析XML
使用simplexml_load_file()函数加载XML到一个对象中去:
$xml = simplexml_load_file('filename.xml');
(如果在一个字符串中存在一些XML,可以用simplexml_load_string()来提取。)
之后,有多种访问XML数据的方法。要引用特定元素,使用$xml->elementname
的格式。如果相同的元素有多个副本,可以向数组一样对待:
$xml->elementname[0];
对于嵌套的元素只要继续该语法即可。
使用foreach循环,容易访问树中的每一个元素:
foreach ($xml->product as $product) {
echo $product->name;
echo $product->size;
属性也很容易访问,像数组一样引用它们即可:
$xml->elementname['attribute'];
示例程序:
<?php
//读取XML文件
$xml = simplexml_load_file('store.xml');
//处理product
foreach ($xml->product as $product) {
echo "<div>".$product->name."大小:".$product->size;
if (isset($product->picture['filename'])) {
echo "<img src=\"{$product->picture['filename']}\">";
}
echo "</div>";
}
?>
所用XML文件为:
<?xml version="1.0" encoding="utf-8"?>
<!-- store.xml -->
<store>
<product>
<name>T-Shirt</name>
<size>XL</size>
</product>
<product>
<name>Sweater</name>
<size>L</size>
<picture filename="sweater.jpg" />
</product>
</store>
添加一些样式后在浏览器运行的结果: