xsd-XML名称空间和属性

我试图了解名称空间如何在XML中工作。 当我有一个像foo:bar这样的元素时,这些属性通常将没有名称空间。 但是有时候他们会。 即使声明了默认名称空间,属性也位于元素的名称空间中吗? 查看xsd中的xhtml,似乎属性是架构的一部分,应该在xhtml的命名空间中,但是它们从未以这种方式呈现...

user4315 asked 2020-08-11T15:52:46Z
4个解决方案
53 votes

大多数时候,属性不会出现在任何命名空间中。 命名空间规范说(强调我的):

默认名称空间声明适用于其范围内的所有非前缀元素名称。 默认名称空间声明不适用于属性名称; 无前缀属性的解释取决于它们出现的元素。

大多数XML词汇表使用非命名空间属性是有原因的:
当元素具有名称空间并且这些元素具有属性时,就不会造成混淆:属性属于元素,元素属于名称空间。 在属性上添加名称空间前缀只会使所有内容变得更加冗长。

那么为什么命名空间属性存在?
因为某些词汇表对大多数属性都有用,所以在与其他词汇表混合使用时可以做到这一点。 最著名的示例是XLink。

最后,W3C XML Schema拥有一种非常简单的方法(<schema attributeFormDefault="qualified">),将属性声明为位于名称空间中,即使您使用默认名称空间,也迫使您在文档中添加前缀。

Bart Schuller answered 2020-08-11T15:53:22Z
15 votes

使用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"/>
jelovirt answered 2020-08-11T15:53:47Z
9 votes

今天,当我使用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>

这太不切实际了,以至于我只是决定摆脱所有全局属性,然后在本地声明它们。 在我给的例子中,维奇看起来像这样:

<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”的味道,因此我决定坚持使用第一个解决方案,并在本地声明我的所有属性。

Diego Tercero answered 2020-08-11T15:55:01Z
3 votes

在w3c上阅读6.1命名空间作用域和6.2命名空间默认值。

基本上:

声明前缀的名称空间声明的范围从出现它的起始标签的开始一直延伸到相应结束标签的末尾

但是,这里的文本似乎没有解释a的意思是a:foo:a还是上下文中的默认名称空间。 我假设它没有引用foo:a,而是文档默认的名称空间a。 至少考虑此报价:

这样的名称空间声明适用于其范围内其前缀与声明中指定的前缀匹配的所有元素和属性名称。

就是 名称空间“ foo:”仅适用于以foo为前缀的元素:

Staale answered 2020-08-11T15:55:44Z
translate from https://stackoverflow.com:/questions/41561/xml-namespaces-and-attributes