也许问题的标题是误导性的,那是因为我无法用一句话来解释我的问题。
在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
命名空间。
在我看来,这两句话相互冲突。
你能告诉我哪一个是正确的吗?每个人的真正含义是什么?
感谢您的时间。
此致
答案 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这是官方文档。
关于您正在阅读的教程。这个档案:
<?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>
如果仔细查看上面的示例,您可能会看到关联:
schema
,complexType
和element
元素以及string
类型都属于http://www.w3.org/2001/XMLSchema
命名空间。http://www.w3schools.com
命名空间的元素或属性,因为这是一个架构,它实际上定义了这些元素。MyType
复杂类型是http://www.w3schools.com
命名空间的一部分。这是因为它在架构中声明,架构的targetNamespace
为http://www.w3schools.com
。由于该命名空间已映射到xyz
前缀,因此当您引用时,您需要prefix
该type
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>
类型的方式相同。您也可以像这样编写上述架构。这没什么区别:
http://www.w3.org/2001/XMLSchema
现在请注意,是默认命名空间,而且它是xs
,因此该命名空间的所有类型和元素都没有前缀。
但最好遵循惯例并将前缀映射到XSD名称空间(通常为xsd
或ns1
)。
实际上,他们没有冲突。但它们写得不好(或许可能是在原始背景下)。第一个:
架构中使用的元素和数据类型来自&#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,但是当你引用一个组件时,请考虑默认命名空间(或带有前缀的命名空间)。