无处不在的 XML
除了可以表示结构化和半结构化的数据之外,XML 还有许多其他特性,使其成为一种被广泛采用的数据表示格式。XML 是可扩展的,与平台无关的,并且由于其完全采用 Unicode 而支持国际化。XML 是基于文本的格式,因此,用户可以根据需要使用标准的文本编辑工具读取和编辑 XML 文档。
XML 的可扩展性表现在多个方面。首先,与 HTML 不同,XML 没有固定的词汇表。相反,用户可以使用 XML 定义特定的应用程序或行业专用的词汇表。其次,与使用其他格式的应用程序相比,处理或使用 XML 格式的应用程序对 XML 结构的更改更具“抵抗力”,只要这些更改是附加的。例如,如果某个应用程序主要处理具有
在交换文档的过程中,XML 架构可以描述 XML 生成程序与使用程序之间的约定,因为它描述了这二者之间的有效 XML 消息的组成。虽然存在大量用于 XML 的架构语言,从 DTD 到 XDR,但目前最权威的是 W3C XML 架构定义语言,通常简称为 XSD。
XSD 在 XML 架构语言中是独一无二的,因为它最先尝试扩展 XML 架构的作用,使之不再局限于仅用来描述两个实体交换文档时的约定。XSD 引入了“后架构验证信息集 (Post Schema Validation Infoset,PSVI)”的概念。一个完整的 XSD 处理器接受 XML 信息集作为输入,并在验证时将其转换为后架构验证信息集 (PSVI)。PSVI 是初始的输入 XML 信息集,带有添加的新信息项和添加到现有信息项中的新属性。W3C XML Schema 推荐列出了后架构验证的信息集的组成要素。
类型注释是 PSVI 组成要素中很重要的一类。元素和属性需进行严格的类型定义,并具有与之相关的数据类型信息。经过严格类型定义的 XML 有很多用途,可以使用 .NET Framework 的 XmlSerializer 等技术将其映射到对象,可以使用 SQLXML 和 .NET Framework 的 DataSet 技术将其映射到关系表格,或者使用利用了严格类型机制的 XML 查询语言,如 XPath 2.0 和 XQuery 对其进行处理。
以下示例是一个架构片段,描述了 XML 文档剖析 一节中示例文档的 items元素。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="items">
<xs:complexType>
<xs:sequence>
<xs:element ref="compact-disc" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="compact-disc">
<xs:complexType>
<xs:sequence>
<xs:element name="price" type="xs:decimal" />
<xs:element name="artist" type="xs:string" />
<xs:element name="title" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
基于树模型的 API
树模型 API 将 XML 文档呈现为由节点组成的树,这个树通常可以立即加载到内存中。最常用的 XML 树模型 API 是 W3C 文档对象模型 (DOM)。DOM 支持以编程方式读取、处理和修改 XML 文档。
以下示例使用 .NET Framework 中的 XmlDocument 类获取 items元素中第一个 compact-disc的艺术家姓名和标题。
using System;
using System.Xml;
public class Test{
public static void Main(string[] args){
XmlDocument doc = new XmlDocument();
doc.Load("test.xml");
XmlElement firstCD = (XmlElement) doc.DocumentElement.FirstChild;
XmlElement artist =
(XmlElement) firstCD.GetElementsByTagName("artist")[0];
XmlElement title =
(XmlElement) firstCD.GetElementsByTagName("title")[0]
Console.WriteLine("Artist={0}, Title={1}", artist.InnerText, title.InnerText);
}
}
基于游标的 API
XML 游标 API 就像在 XML 文档中移动的镜头,对准被定向的文档的各个方面。.NET Framework 中的 XPathNavigator 类就是一个 XML 游标 API。XML 游标 API 与树模型 API 相比,具有不必将整个文档加载到内存中的优势,这样便于对 XML 生成程序中按需生成文档的部分进行优化。
以下示例使用 .NET Framework 中的 XPathNavigator 类获取 items元素中第一个 compact-disc的艺术家姓名和标题。
using System;
using System.Xml;
using System.Xml.XPath;
public class Test{
public static void Main(string[] args){
XmlDocument doc = new XmlDocument();
doc.Load("test.xml");
XPathNavigator nav = doc.CreateNavigator();
nav.MoveToFirstChild(); //从根节点移至文档元素 (items)
nav.MoveToFirstChild(); //从 items 元素移至第一个 compact-disc 元素
//从 compact-disc 元素移至 artist 元素
nav.MoveToFirstChild();
nav.MoveToNext();
string artist = nav.Value;
//从 artist 元素移至 title 元素
nav.MoveToNext();
string title = nav.Value;
Console.WriteLine("Artist={0}, Title={1}", artist, title);
}
}
流式 API
使用处理 XML 的流式 API 时,用户只需在内存中存储要处理的当前节点的上下文,即可处理 XML 文档。此类 API 可以处理大型的 XML 文件,而不会占用庞大的内容空间。用于 XML 处理的流式 API 主要有两种类型:基于推进的 XML 分析器和基于拉出的 XML 分析器。
基于推进的分析器(如 SAX)的工作方式是在 XML 数据流中移动,并在遇到 XML 节点时将事件“推进”到已注册的事件处理程序(回调方法)。基于拉出的分析器(如 .NET Framework 中的 XmlReader 类)则在 XML 数据流中用作只向前的游标。
以下示例使用 .NET Framework 中的 XmlReader 类获取 items元素中第一个 compact-disc的艺术家姓名和标题。
using System;
using System.Xml;
public class Test{
public static void Main(string[] args){
string artist = null, title = null;
XmlTextReader reader = new XmlTextReader("test.xml");
reader.MoveToContent(); //move from root node to document element (items)
/* 保持读取,直至获得第一个 <artist> 元素 */
while(reader.Read()){
if((reader.NodeType == XmlNodeType.Element) && reader.Name.Equals("artist")){
artist = reader.ReadElementString();
title = reader.ReadElementString();
break;
}
}
Console.WriteLine("Artist={0}, Title={1}", artist, title);
}
}