2008-09-03 98 views
35

我想了解命名空间如何在XML中工作。当我有像foo:bar这样的元素时,这些属性通常没有名称空间。但有时他们会。元素名称空间中的属性,即使默认名称空间已被声明?查看xhtml的xsd,似乎属性是模式的一部分,应该位于xhtml的名称空间中,但它们绝不会以这种方式呈现...XML命名空间和属性

回答

2

在w3c上阅读6.1 Namespace Scoping6.2 Namespace Defaulting

基本上:

一个命名空间声明声明前缀的范围从开始标记的开始在它出现在相应的结束标记的端

但是延伸,这里的文本似乎没有解释,如果意味着a是foo:a或上下文中的默认命名空间。我会假设它不会引用foo:a,而是文档的默认命名空间a。至少考虑到这句话:

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

即,命名空间“FOO:”只适用于以foo前缀的元素:

11

实施例以说明使用Clark notation,其中命名空间前缀被替换为在大括号中的命名空间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"/> 
+2

你如何解释在第二和第三个例子中,属性`qux`不会继承名字空间`http:// www.foo.com /`,即使它是元素的默认名称空间? – 2011-01-10 16:00:16

46

大多数情况下,属性不会出现在任何名称空间中。该namespace spec说(强调矿):

默认命名空间声明适用于在其范围内的所有前缀的元素名。默认名称空间声明做不是直接适用属性名称;前缀属性的解释是由它们出现的元素决定的。

还有一个原因,大多数XML词汇使用非命名空间属性:
当你的元素有一个命名空间,这些元素具有属性,那么就没有困惑:该属性属于你的元素,属于你的名字空间。给这些属性添加一个名称空间前缀只会使一切更加冗长。

那么为什么名称空间属性存在?
因为有些词汇表对大多数属性做了有用的工作,并且可以在与其他词汇表混合时做到这一点。最着名的例子是XLink

最后,W3C XML架构具有声明你的属性在一个命名空间之中,迫使你前缀他们在你的文件,甚至您使用默认的命名空间的一切都太容易的方式(<schema attributeFormDefault="qualified">)。

+1

这是一个非常有知识的答案,考虑你在这里所说的话你会认为这个陈述是错误的:“所有属性无论它们在哪里都必须加入前缀属于一个名字空间”上下文:http://stackoverflow.com/问题/ 10917416/configurations-an-xml-namespace/10917629#comment14238724_10917629(熊猫的回答) – 2012-06-06 16:08:04

+0

@Bart Schuller:这些属性最可能属于你的元素,但他们并不一定非要。 – 2014-09-16 13:57:28

7

这个属性/命名空间主题与我在使用XSD时花了一些时间来理解。 如果有人遇到同样的问题,我会与您分享这些经验。

在Schema Document中,我正在处理一些元素引用的几个全局属性。为了简化这里的事情,我们假设我所说的这个XSD是关于Customer

我们称之为全局属性Id。并用它的根元素客户

我的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"> 

标识属性声明是这样的:

<xs:attribute name="Id" type="xs:positiveInteger"/> 

和我客户元素使用像这样的属性:

<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> 

我发现很难找到什么我在这里谈论的网络提供一些参考。我终于找到this post于该手写笔XSD论坛,一个名为斯蒂恩莱曼人提议要么在本地声明的属性或属性组

内声明它“这样的属性声明 本身不再是全球”

这最后的解决方案具有“哈克”的味道,所以我决定坚持与第一个解决方案,我的所有属性本地申报。