我试图了解名称空间如何在XML中工作。 当我有一个像foo:bar这样的元素时,这些属性通常将没有名称空间。 但是有时候他们会。 即使声明了默认名称空间,属性也位于元素的名称空间中吗? 查看xsd中的xhtml,似乎属性是架构的一部分,应该在xhtml的命名空间中,但是从来没有那样显示它们...
大多数时候,属性不会出现在任何命名空间中。命名空间规范说(强调我的):
A default namespace declaration applies to all unprefixed element names within its scope. Default namespace declarations do not apply directly to attribute names; the interpretation of unprefixed attributes is determined by the element on which they appear.
大多数XML词汇表使用非命名空间属性是有原因的:
当元素具有名称空间并且那些元素具有属性时,就不会造成混淆:属性属于元素,元素属于名称空间。在属性上添加名称空间前缀只会使所有内容变得更加冗长。
那么为什么命名空间属性存在?
因为某些词汇表主要对属性有用,所以在与其他词汇表混合使用时可以做到这一点。最著名的示例是XLink。
最后,W3C XML Schema拥有一种非常简单的方法(),将属性声明为位于名称空间中,即使您使用默认名称空间,也迫使您在文档中添加前缀。
使用Clark表示法的示例,其中用大括号将名称空间前缀替换为名称空间URL:
1 2 3 4 5 6 7 8 9
| <bar xmlns:foo="http://www.foo.com/"
foo:baz="baz"
qux="qux"/>
<bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
foo:baz="baz"
qux="qux"/>
<foo:bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
foo:baz="baz"
qux="qux"/> |
是
1 2 3 4 5 6 7 8 9
| <{}bar
{http://www.foo.com/}baz="baz"
{}qux="qux"/>
<{http://www.foo.com/}bar
{http://www.foo.com/}baz="baz"
{}qux="qux"/>
<{http://www.foo.com/}bar
{http://www.foo.com/}baz="baz"
{}qux="qux"/> |
今天,当我使用XSD时,与此属性/命名空间主题相关的一些事情使我花了一些时间来理解。
如果有人碰巧遇到相同的问题,我将与您分享这种经验。
在我正在研究的模式文档中,一些元素引用了几个全局属性。为了简化起见,我们假设我正在谈论的XSD是关于客户的。
让我们称这些全局属性Id之一。和使用它的根元素Customer
我的XSD声明看起来像这样:
1 2 3 4
| <?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属性声明如下所示:
1
| <xs:attribute name="Id" type="xs:positiveInteger"/> |
我的Customer元素使用了如下属性:
1 2 3 4 5 6
| <xs:element name="Customer">
<xs:complexType>
<xs:attribute ref="Id" use="required"/>
<!-- some elements here -->
</xs:complexType>
</xs:element> |
现在,假设我想这样声明一个Customer XML文档:
1 2 3 4
| <?xml version="1.0" encoding="utf-8"?>
<Customer Id="1" xmlns="http://schemas.mycompany.com/Customer/V1">
<!-- ... other elements here -->
</Customer> |
我发现不能:当全局声明该属性时,该属性与引用该元素的元素不在同一命名空间中。
我发现用XSD定义的唯一解决方案是两次声明名称空间:一次不带前缀以使其成为元素的默认名称空间,一次带前缀以使其与属性一起使用。这就是它的样子:
1 2 3 4 5
| <?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> |
这太不切实际了,以至于我决定放弃所有全局属性,然后在本地声明它们。在我给的例子中,维奇看起来像这样:
1 2 3 4 5 6
| <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的人建议要么在本地声明属性,要么在属性组中声明它。
"so that the attribute declaration
itself is no longer global"
最后一个解决方案具有" hacky"的味道,因此我决定坚持使用第一个解决方案,并在本地声明我的所有属性。
在w3c上阅读6.1命名空间范围和6.2命名空间默认值。
基本上:
The scope of a namespace declaration declaring a prefix extends from the beginning of the start-tag in which it appears to the end of the corresponding end-tag
但是,这里的文本似乎没有解释a的意思是a:foo:a还是上下文中的默认名称空间。我假设它没有引用foo:a,而是文档的默认名称空间a。至少考虑此报价:
Such a namespace declaration applies to all element and attribute names within its scope whose prefix matches that specified in the declaration.
就是名称空间" foo:"仅适用于以foo为前缀的元素: