XML(简介)
XML(可扩展标记语言)在 20 世纪 90 年代后期登上舞台后,就一直是众多活动和狂热思索的焦点。XML 只是基于普通文本,但却提供了几乎可以在任何两个应用程序间共享数据的方式。
虽然 XML 在概念上很简单,但对 XML 的处理却通常很烦琐(需要编写大量重复性的代码)和复杂(很多容易被忽视的细节导致错误)。
什么时候使用 XML?
什么时候在Web 应用程序中使用 XML?
你需要处理已经保存在 XML 中的数据时。
你希望用 XML 保存数据并为将来可能的整合做准备时。(XML 在应用程序整合的场景中最有意义)
你希望使用依赖于 XML 的技术时。(Web 服务使用各种建立在 XML 上的标准)
注解:
必须理解的一个重要概念是,存储数据时必须决定两件事情:
确定数据结构化的方式(逻辑格式)
确定数据保存的方式(物理存储)
XML 是格式的选择而不是存储的选择。也就是说,即使你决定用 XML 保存数据,你还要决定是保存到数据库字段里,还是要插入到一个文件里,或者只是以字符串或其他对象的形式保存在内存中。
XML 简介
XML 规范是由 W3C(World Wide Web Consortium)定义的一组指南,用于以纯文本的形式描述结构化数据,一种基于尖括号间标签的标记语言。
XML 没有一组固定的标签。相反,XML 是一种可用于创建其他标记语言的元语言。
下面的文档显示一个保存产品类别的自定义 XML 格式:
<productCatalog>
<catalogName>Acme Fall 2015 Catalog</catalogName>
<expiryDate>2015-01-01</expiryDate>
<products>
<product id=”1001″>
<productName>Magic Ring</productName>
<productPrice>342.10</productPrice>
<inStock>true</inStock>
</product>
<product id=”1002″>
<productName>Flying Carpet</productName>
<productPrice>982.99</productPrice>
<inStock>true</inStock>
</product>
</products>
</productCatalog>
标签可以自由使用最能描述你的数据的任意名称,正是这种灵活性使得 XML 非常成功。当然,灵活性也会有缺点。不同公司完全可用不同的标签名来描述相似的数据,尽管所有应用程序都能够解析 XML 数据,但数据的写入者和读取者需要对标签和结构达成共识,才能使读取者可用解释数据并抽取有意义的信息。
XML 的优点
今天,XML 比过去任何一天都更为有用。现代应用程序使用 XML 的好处有以下几点:
适应性。XML 无处不在,无论什么时候需要共享数据,XML 都会成为首选目标。
扩展性和灵活性。XML 不会强加任何数据语义的规则,适用于任意数据的类型并且实现的代价很低。
相关标准和工具
。XML 成功的另一个原因在于创建和处理 XML 的工具(解析器)和相关标准(XML架构、XPath、XSLT)。这样几乎每种语言的开发者都有现成的组件用于阅读 XML,按某种规则(被称作架构)验证 XML 的有效性,将 XML 转换格式等。
格式良好的 XML
XML 是一个非常严格的标准,这种严格性是用于保留广泛的兼容性的。(臭名昭著的 HTML 语言就是在没有这种严格性标准下的产物)
所有的 XML 解析器都会执行一些基本的质量检查。如果一个 XML 文档不能满足所有标准,它就会被彻底拒绝。否则,它就被认为是格式良好的。格式良好的 XML 未必就是正确的 XML ,例如含有错误数据,但 XML 解析器能够解析它。
XML 文档必须满足下面这些条件才能被认为是格式良好的:
每个开始标签必须有一个对应的结束标签
空元素必须以“/>”结束
元素可以嵌套但不能交错
XML 是严格区分大小写的,因此
一个元素不能有两个或更多的同名特性,但是可以嵌套多个同名的元素
一个文档只可以有一个根元素
所有特性在值的前后都要有引号
注释不能放入标签中(它们包含在
标记中)
XML 命名空间
随着 XML 标准的成长,已创建了数十种 XML 标记语言(通常叫做 XML 语法)。其中很多属于特定的行业、流程和信息类型。如果你需要同时组合两个具有相同名称元素的 XML 语法,会发生什么呢?另一个更典型的问题是如何区分它们?
解决办法在于 XML 命名空间标准。这个标准的核心思想是所有的 XML 标记语言都拥有能够唯一区分相关元素的命名空间。简单的说,命名空间可以在整合时消除同名元素的歧义。
所有的 XML 命名空间都使用 URI(Universal Resource Identifiers,统一资源标识符),一般看起来和网页的 URL 相似。例如,http://www.mycompany.com/mystandard 是一种典型的命名空间,但这不是必要的(也不应该被假设),命名空间可以是任意文本序列,标准是为了确保它的唯一性。
要指定某个元素属于特定的命名空间,只需在开始标签中加入 xmlns(XML Name Space)特性表明要使用的命名空间即可。例如,下面这个元素是http://mycompany/OrderML 命名空间的一部分。
你一定会厌倦在所有元素上加入这个特性的烦琐操作,幸好,如果像下面这样加入命名空间,它会成为所有子元素默认的命名空间:
<product xmlns=”http://mycompany/OrderML”>
<productName>Flying Carpet</productName>
<productPrice>982.99</productPrice>
<inStock>true</inStock>
</product>
你还可以自定义命名空间前缀,在 xmlns 特性中插入一个冒号和一个你想用作前缀的字符:
<ord:order xmlns:ord=”http://mycompany/OrderML”
xmlns:cli=”http://mycompany/ClientML”>
<cli:client>
<cli:firstName>…</cli:firstName>
<cli:lastName>…</cli:lastName>
</cli:client>
<ord:orderItem>…</ord:orderItem>
<ord:orderItem>…</ord:orderItem>
</ord:order>
XML 架构
XML 的灵活性也带来了一些问题。世界各地的开发人员都使用你的 XML 格式,怎样才能保证所有人都遵守规则?
解决办法是创建一个格式文档,它定义你的自定义标记语言的规则,它被称为架构。这些规则不会包括语法细节(那是 XML 标准所要规定的),架构文档需要定义的是符合你的数据类型的逻辑规则,它包括以下几项:
文档词汇。它定义了哪些元素或特性的名字可以出现在你的 XML 文档中。
文档结构。它定义了标签放在哪儿,可以指定标签之间的顺序,还可以指定某个元素可以出现的次数。
支持的数据类型。可以定义数据是文本,或者必须是可以解析的数值数据、日期信息等。
允许的数据范围。可将数值限制在范围内,文本限定在特定长度内,强迫正则表达式模式匹配,或者限制仅可以是某些特定的值。
下面的这个 XML 架构定义了前面所示的产品类别规则:
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<xsd:element name=”productCatalog”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”CatalogName” type=”xsd:string” />
<xsd:element name=”expiryDate” type=”xsd:date” />
<xsd:element name=”products”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”product” type=”productType” maxOccurs=”unbounded” />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name=”productType”>
<xsd:sequence>
<xsd:element name=”productName” type=”xsd:string” />
<xsd:element name=”productPrice” type=”xsd:decimal” />
<xsd:element name=”inStock” type=”xsd:boolean” />
</xsd:sequence>
<xsd:attribute name=”id” type=”xsd:integer” use=”required” />
</xsd:complexType>
</xsd:schema>
所有的架构文档都是以根元素 <schema> 开头的 XML 文档
所有可用的元素都已经在 XML 架构空间定义了(http://www.w3.org/2001/XMLSchema)
你的架构文档必须使用正确的命名空间名(前缀一般是 xsd 或 xs ,你也可以自定义)
在 <schema> 元素内,有两种类型的定义
<element> 定义目标文档必须遵循的结构
<complexType> 定义文档结构较小的数据结构
<element>标签是架构的核心,同时它也是所有验证的起点
在这个示例中,<element>标签确定产品类别必须以一个叫做<productCatalog>的根元素开始。<productCatalog>元素内部是一个由3个元素组成的序列。第一个是<catalogName>,它包含普通文本;第二个是<expiryDate>,它包含符合日期呈现规则的文本;第三个是<products>,它包含<product>元素的列表。
每个<product>元素都是一个复杂的类型,因此文档后面又使用<complexType>进行了定义。这个复杂类型(名为<productType>)由含有产品信息的 3 个元素所组成的序列构成。这些元素分别保存文本(<productName>)、十进制数(<productPrice>)、布尔值(<inStock>)。这个复杂类型还包括一个必须的特性 id。