提问人:user4315 提问时间:9/3/2008 更新时间:3/13/2023 访问量:34816
XML 命名空间和属性
XML namespaces and attributes
问:
我试图了解命名空间在XML中是如何工作的。当我有像 foo:bar 这样的元素时,属性通常没有命名空间。但有时他们会的。该属性是否在元素的命名空间中,即使已声明默认命名空间也是如此?查看 xhtml 的 xsd,似乎这些属性是架构的一部分,应该位于 xhtml 的命名空间中,但它们从未以这种方式呈现......
答:
在 w3c 上阅读 6.1 命名空间范围和 6.2 命名空间默认值。
基本上:
声明前缀的命名空间声明的范围从出现前缀的开始标记的开头延伸到相应结束标记的末尾
但是,此处的文本似乎没有解释 means a 是 foo:a 还是上下文中的默认命名空间。我假设它不是指 foo:a,而是文档默认命名空间 a。至少考虑这句话:
此类命名空间声明适用于其作用域内所有元素和属性名称,其前缀与声明中指定的前缀匹配。
即。命名空间 “foo:” 仅适用于以 foo 为前缀的元素:
XML 1.1(第二版)中的命名空间声明“无前缀属性名称的命名空间名称始终没有值”,并且“无前缀属性的解释由它们出现的元素决定”
下面是使用 Clark 表示法进行说明的示例,其中命名空间前缀替换为大括号中的命名空间 URL:
<bar xmlns:foo="http://www.example.com/"
foo:baz="baz"
qux="qux"/>
<bar xmlns="http://www.example.com/" xmlns:foo="http://www.example.com/"
foo:baz="baz"
qux="qux"/>
<foo:bar xmlns="http://www.example.com/" xmlns:foo="http://www.example.com/"
foo:baz="baz"
qux="qux"/>
是
<{}bar
{http://www.example.com/}baz="baz"
{}qux="qux"/>
<{http://www.example.com/}bar
{http://www.example.com/}baz="baz"
{}qux="qux"/>
<{http://www.example.com/}bar
{http://www.example.com/}baz="baz"
{}qux="qux"/>
评论
qux
http://www.foo.com/
大多数情况下,属性不会位于任何命名空间中。命名空间规范说(强调我的):
默认命名空间声明适用于其作用域内的所有无前缀元素名称。默认命名空间声明不直接应用于属性名称;无前缀属性的解释由它们所显示的元素决定。
大多数 XML 词汇表使用非命名空间属性是有原因的:当您的元素具有命名空间并且这些元素具有属性时,就不会混淆:
这些属性属于您的元素,而元素属于您的命名空间。向属性添加命名空间前缀只会使所有内容更加冗长。
那么,为什么存在命名空间属性呢?
因为有些词汇表主要对属性有用,当与其他词汇表混合时可以做到这一点。最著名的例子是 XLink。
最后,W3C XML 架构有一种非常简单的方法 () 将属性声明为位于命名空间中,从而强制您在文档中为它们添加前缀,即使您使用默认命名空间也是如此。<schema attributeFormDefault="qualified">
评论
今天在处理 XSD 时,我花了一些时间才理解与此属性/命名空间主题相关的内容。 我将与您分享此经验,以防有人碰巧遇到同样的问题。
在我正在处理的架构文档中,有一些元素引用了几个全局属性。为了简化这里的事情,让我们假设我所说的这个 XSD 是关于客户的。
我们将这些全局属性之一称为 Id。以及使用它的根元素 Customer
我的 XSD 声明如下所示:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://schemas.mycompany.com/Customer/V1"
targetNamespace="http://schemas.mycompany.com/Customer/V1"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
我的 Id 属性声明如下所示:
<xs:attribute name="Id" type="xs:positiveInteger"/>
我的 Customer 元素使用了这样的属性:
<xs:element name="Customer">
<xs:complexType>
<xs:attribute ref="Id" use="required"/>
<!-- some elements here -->
</xs:complexType>
</xs:element>
现在,假设我想声明一个客户XML文档,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Customer Id="1" xmlns="http://schemas.mycompany.com/Customer/V1">
<!-- ... other elements here -->
</Customer>
我发现我不能:当属性是全局声明时,它与引用它的元素不在同一个命名空间中。
我发现,像这样定义 XSD 的唯一解决方案是声明命名空间两次:一次不带前缀,以便使其成为元素的默认命名空间,一次带前缀,以便将其与属性一起使用。所以这就是它的样子:
<?xml version="1.0" encoding="utf-8"?>
<Customer cus:Id="1" xmlns="http://schemas.mycompany.com/Customer/V1"
xmlns:cus="http://schemas.mycompany.com/Customer/V1">
<!-- ... other elements here -->
</Customer>
这太不切实际了,以至于我决定去掉所有的全局属性,并在本地声明它们。在我在这里给出的例子中,它看起来像这样:
<xs:element name="Customer">
<xs:complexType>
<xs:attribute name="Id" type="xs:positiveInteger" use="required"/>
<!-- some elements here -->
</xs:complexType>
</xs:element>
我发现很难在网上找到一些关于我在谈论的内容的参考资料。我最终在 Stylus XSD 论坛上找到了这篇文章,其中一位名叫 Steen Lehmann 的人建议要么在本地声明属性,要么在属性组中声明它
“这样属性声明 本身不再是全球性的”
最后一个解决方案有一种“hacky”的味道,所以我决定坚持使用第一个解决方案并在本地声明我的所有属性。
评论