固定属性是 XML 1.0 文档类型定义(document type definition (DTD))的特性,也是其它一些模式系统的特性。您可以对一个元素声明一个属性,使它被认为始终是存在的并且将始终具有一个给定值(固定值)。这样,您可以设计存在某些属性的 DTD,但这些属性不必出现在 XML 文档的主体中,从而减少混乱并且减少了用户必须记住并输入的详细信息。
固定属性回顾在 中,eg.dtd 是一个定义了固定属性的 DTD。
清单 1. eg.dtd1
2
3
4
5
6
| <!ELEMENT x (#PCDATA)>
<!ATTLIST x
f CDATA #FIXED "a"
y CDATA "b"
z CDATA #IMPLIED
>
|
这里,我声明了一个元素 x 。其内容是简单文本( #PCDATA )。我还为该元素声明了一组属性。 f 是简单字符数据类型( CDATA )的固定属性。这意味着 x 元素将始终有一个值为 a 的 f 属性。为了举例说明一些更常用的属性定义,我定义了 y 和 z ,它们都不是固定属性。这两者都是简单字符数据类型(简单地说,就是任意字符串)。 y 可用于具有任何值的实例,但如果省略了对它进行赋值,则假定它的值为 b 。 z 可用于具有任何值的实例,如果省略了对它进行赋值,它就没有值(这就是并不直观的关键字 #IMPLIED 的含义)。
在 中,eg1.xml 是说明这一点的示例实例。
清单 2. eg1.xml1
2
3
| <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE x SYSTEM "eg.dtd">
<x f="a" y="bb" z="cc">Hello world</x>
|
给出了 f 属性,这没有问题。也给出了另外两个属性,并且 y 的值与所提供的缺省值不同。这也没有问题,不过如果与 f 属性的声明相矛盾的话,就有问题了。下面是一个 无效文档,因为它使用了值不为 a 的 f 。
清单 3. f 属性的值无效的文档1
2
3
| <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE x SYSTEM "eg.dtd">
<x f="aa" y="bb" z="cc">Hello world</x>
|
然而,完全省略 f 是绝对没有问题的,因而 实际上相当于 :
清单 4. 不带 f 属性的有效文档1
2
3
| <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE x SYSTEM "eg.dtd">
<x y="bb" z="cc">Hello world</x>
|
隐藏名称空间声明固定属性的常见用法是隐藏标记的详细信息,而这些详细信息是必需的,但您又不希望让文档作者必须记住并输入它们。这样的一个示例是隐藏名称空间声明。假设我的一个词汇表有如下所示的实例文档:
清单 5. 在 memo.dtd 中声明名称空间1
2
3
4
5
6
7
8
9
| <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE memo SYSTEM "memo.dtd">
<memo xmlns='http://spam.com' version="1.0">
<date form="iso-8601">2002-08-14</date>
This is just to <strong>say</strong>:
I ate the eggs you left in the fridge
And were probably saving for breakfast.
Do you know? They were <emph>quite</emph> rotten.
</memo>
|
然而,您不希望作者在每篇文档中都必须输入名称空间声明 xmlns='http://spam.com' 和 memo 版本标记 version="1.0" 。 是 DTD 片段,它将固定属性声明添加到 memo.dtd 中的 memo 元素。
清单 6. 将名称空间声明为固定属性1
2
3
4
| <!ATTLIST memo
xmlns CDATA #FIXED "http://spam.com"
version CDATA #FIXED "1.0"
>
|
实际上,所选的 DTD 设置了文档的名称空间和版本。随后可以简单地将实例写成:
清单 7. 名称空间为固定属性的 memo.dtd1
2
3
4
5
6
7
8
9
| <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE memo SYSTEM "memo.dtd">
<memo>
<date form="iso-8601">2002-08-14</date>
This is just to <strong>say</strong>:
I ate the eggs you left in the fridge
And were probably saving for breakfast.
Do you know? They were <emph>quite</emph> rotten.
</memo>
|
而这个清单相当于 。
这样做的一个弊端是它强制文档作者使用缺省名称空间(这意味着不使用前缀)。例如,根据 DTD,下面的文档是无效的:
清单 8. 无效的示例1
2
3
4
5
6
7
8
9
| <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE memo SYSTEM "memo.dtd">
<m:memo xmlns:m="http://spam.com">
<m:date form="iso-8601">2002-08-14</m:date>
This is just to <m:strong>say</m:strong>:
I ate the eggs you left in the fridge
And were probably saving for breakfast.
Do you know? They were <m:emph>quite</m:emph> rotten.
</m:memo>
|
问题是:就 DTD 的观点而言,元素 m:memo 和 memo 是不同的,即使从 XML 名称空间的观点来说它们或许相同。这是 DTD 的常见问题,有一些解决它的成熟的变通方法。但实际上这个问题不会经常出现,因为如果目标是为作者减少麻烦,那么如果不是必须的话,作者不太可能使用前缀。
W3C XML 模式语言(XML Schema Language)支持名称空间声明和固定属性声明。下面的片段与 中版本属性声明类似。
清单 9. 声明名称空间1
| <xsd:attribute name="version" type="xsd:string" fixed="1.0"/>
|
遗憾的是,在 W3C XML 模式中不能简单地将名称空间声明设置为固定属性,因为它用特殊规则处理名称空间声明。
结束语也可将固定属性用作它途。在有限制的情况下,可用它们来调整略微不同的词汇表。正如使用任何内置的 XML 工具一样,重要的是熟悉它们以便在需要时能够使用它们。 |