XML名称空间和属性
我试图了解名称空间如何在XML中工作。当我有一个像foo:bar这样的元素时,这些属性通常将没有名称空间。但是有时候他们会的。即使声明了默认名称空间,属性也位于元素的名称空间中吗?查看xsd中的xhtml,似乎属性是架构的一部分,应该在xhtml的命名空间中,但是它们从来没有以这种方式呈现...
解决方案
回答
在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.
IE。名称空间" foo:"仅适用于以foo:开头的元素:
回答
使用Clark表示法的示例,其中用大括号将名称空间前缀替换为名称空间URL:
<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"/>
是
<{}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"/>
回答
大多数情况下,属性不会出现在任何命名空间中。命名空间规范说(强调我的):
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拥有一种非常简单的方法(<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>
现在,假设我要声明一个Customer 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>
这太不切实际了,以至于我决定放弃所有全局属性,并在本地声明它们。就我在此给出的示例而言,Wich看起来应该像这样:
<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"的味道,因此我决定坚持使用第一个解决方案,并在本地声明我的所有属性。