XSD:命名空间和默认命名空间之间的区别是什么

时间:2014-06-19 18:28:56

标签: xml namespaces xsd xml-namespaces

也许问题的标题是误导性的,那是因为我无法用一句话来解释我的问题。

w3school tutorial中,有一个例子:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3schools.com"
           xmlns="http://www.w3schools.com"
           elementFormDefault="qualified">
    ...
    ...
</xs:schema>

作者已声明:xmlns:xs="http://www.w3.org/2001/XMLSchema"表示:

  

架构中使用的元素和数据类型来自&#34; http://www.w3.org/2001/XMLSchema&#34;命名空间。它还指定来自&#34; http://www.w3.org/2001/XMLSchema&#34;的元素和数据类型。名称空间应该以xs为前缀。

但是,作者还指出targetNamespace="http://www.w3schools.com"表示:

  

此架构定义的元素(注释,to,from,heading,body。)来自&#34; http://www.w3schools.com&#34;命名空间。

我在理解前面的段落时遇到了问题。第一个声明元素来自http://www.w3.org/2001/XMLSchema命名空间,尽管第二个段落声明元素来自http://www.w3schools.com命名空间。

在我看来,这两句话相互冲突。

你能告诉我哪一个是正确的吗?每个人的真正含义是什么?

感谢您的时间。

此致

2 个答案:

答案 0 :(得分:9)

默认名称空间,限定名称和前缀

默认命名空间是未映射到任何前缀的命名空间。你使用:

声明它
xmlns="a-string-that-is-usually-an-uri"

如果您在XML文件中有这样的声明,任何未加前缀的元素将属于该命名空间。未加前缀的属性始终属于 no namespace

您可以在XML文档中使用多个名称空间声明,但每个作用域中只能有一个默认名称空间。您也不需要拥有任何默认命名空间。范围由元素本身及其后代组成。在下面的文档中,有两个默认名称空间。 ns2命名空间替换它声明的元素及其后代中的ns1

<root xmlns="ns1">
    <text>This is ns1</text>
    <child xmlns="ns2">
        <text>This is ns2</text>
    </child>
</root>

上面的文档中有两个<text>元素。实际上它们是完全不同的元素,因为每个元素都属于不同的命名空间。它们具有相同的本地名称,但它们的限定名称不同。

如果您有相同名称空间的声明,例如:

xmlns:p="a-string-that-is-usually-an-uri"

您正在使用前缀p映射名称空间,该前缀可以由上下文中的任何元素使用(考虑格式良好的文档,不一定有效)。对于有效文档,作为命名空间一部分的元素应该由它限定,或者作为声明默认命名空间的元素的无前缀的后代(或self),或者作为声明的元素的前缀后代(或self)。映射到该前缀的名称空间。前缀也可用于限定属性。

通过使用前缀,您可以在根元素处拥有所有声明,并且合格元素可以混合使用:

<root xmlns:p="ns1" xmlns:q="ns2" xmlns="ns0">
    <p:text>This is ns1</p:text>
    <q:child xmlns="ns2">
        <q:text>This is ns2</q:text>
        <p:text>This is ns1 again!</p:text>
        <text>This is ns0</text>
    </q:child>
</root>

上面的<text>元素中的每一个都是不同命名空间的一部分。

请花一些时间阅读本指南:Understanding XML Namespaces。它很简短,如果你仔细阅读,你肯定会理解XML中的命名空间如何运作得很好。如果您愿意,还可以阅读XML Namespaces specification这是官方文档。

XSD中的目标命名空间

关于您正在阅读的教程。这个档案:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3schools.com"
           xmlns="http://www.w3schools.com"
           elementFormDefault="qualified">
    ...
    ...
</xs:schema>

具有两个名称空间声明,以及一个目标名称空间声明。由于它也是架构,因此它包含属于目标命名空间类型定义。这可能会令人困惑,因为架构是一个XML文档,它使用XML声明其他XML文档的规则。将XSD文档视为简单的 XML 文档,您将一个名称空间映射到xs前缀,另一个名称空间映射到默认名称空间。您还可以合法使用不同的前缀:

<abc:schema xmlns:abc="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3schools.com"
           xmlns:xyz="http://www.w3schools.com"
           elementFormDefault="qualified">
    <abc:complexType name="MyType"> ...</abc:complexType>
    <abc:element name="myElementOne" type="xyz:MyType" />
    <abc:element name="myElementTwo" type="abc:string" />
</abc:schema>

如果仔细查看上面的示例,您可能会看到关联:

  1. schemacomplexTypeelement元素以及string类型都属于http://www.w3.org/2001/XMLSchema命名空间。
  2. 架构中没有属于http://www.w3schools.com命名空间的元素或属性,因为这是一个架构,它实际上定义了这些元素。
  3. MyType复杂类型是http://www.w3schools.com命名空间的一部分。这是因为它在架构中声明,架构的targetNamespacehttp://www.w3schools.com。由于该命名空间已映射到xyz前缀,因此当您引用时,您需要prefixtype type第一个元素的属性,与第二个元素的string属性引用http://www.w3.org/2001/XMLSchema命名空间的<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns:xyz="http://www.w3schools.com" elementFormDefault="qualified"> <complexType name="MyType"> ...</complexType> <element name="myElementOne" type="xyz:MyType" /> <element name="myElementTwo" type="string" /> </schema> 类型的方式相同。
  4. 您也可以像这样编写上述架构。这没什么区别:

    http://www.w3.org/2001/XMLSchema

    现在请注意,默认命名空间,而且它是xs,因此该命名空间的所有类型和元素都没有前缀。

    但最好遵循惯例并将前缀映射到XSD名称空间(通常为xsdns1)。

    关于冲突的句子

    实际上,他们没有冲突。但它们写得不好(或许可能是在原始背景下)。第一个:

      

    架构中使用的元素和数据类型来自&#34; http://www.w3.org/2001/XMLSchema&#34;命名空间。它还指定来自&#34; http://www.w3.org/2001/XMLSchema&#34;的元素和数据类型。名称空间应该以xs为前缀。

    将XSD文档视为常规XML文件。在任何XML文件中,名称空间声明如xmlns =&#34; ns1&#34;在根元素中声明无前缀元素来自element 默认命名空间。在句子描述的情况下,作者指的是所有前缀元素(例如complexType,,simpleType ) and types (such as序列{{1} } ,整数,十进制) because the xs`前缀映射到XSD名称空间。作者正在讨论XML文件中使用的元素和类型,没有定义。

    下一句是关于targetNamespace,它是特定于XSD规范的属性。它声明了所有类型的命名空间:

      

    的targetNamespace =&#34; HTTP://www.w3schools.com"表示此架构定义的元素(注释,to,from,heading,body。)来自&#34; http://www.w3schools.com&#34;命名空间。

    这是指您分配给类型和元素的名称。当您创建声明该命名空间的实例时,您将使用这些元素:

    <note xmlns="http://www.w3schools.com">...</note>
    

    <x:note xmlns:x="http://www.w3schools.com">...</x:note>
    

    但是在XSD中你是定义它们。您甚至不需要在架构中声明xmlns="http://www.w3schools.com",如果您从未引用(使用type,{{1等属性等等)你在其中创建的任何其他类型或元素。

答案 1 :(得分:0)

   default namespace serve only one purpose, it allows use of namespace qualified xml components without namespace prefix. 

只是给你一个解决上述问题的提示,当你定义一个组件时,你应该考虑它的targetNamespace,但是当你引用一个组件时,请考虑默认命名空间(或带有前缀的命名空间)。