页面w3schools给出 以下作为一种形式的模式声明。
<?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>
在这里,
targetNamespace 定义XML文档的名称空间 定义 - 哪些标签(元素)和哪些属性可以在“this”XSD中定义的XML文档中使用。
xmlns=http://www.w3schools.com/schema/schema_schema.asp
另一方面,是为XML文档中的名称定义默认名称空间 - 那些未定义的名称 在“this”XSD(?)上,解析器首先查找 targetNamespace 中声明的命名空间。如果在那里找不到名字,继续尝试下一个 xmlns (?)
如果我跳过上面架构声明中的 targetNamespace 属性,我究竟会错过什么?虽然我对 xmlns , targetNamespace 多余,因为它们指的是同一个命名空间。
什么 我错过了吗?
注意:我在其他一些讨论中看过What does "xmlns" in XML mean?。
答案 0 :(得分:7)
要了解targetNamespace
和xmlns
之间的区别,请仔细考虑以下内容。
XSD 是一种描述XML模式的语言。 必须以某种方式表达任何计算机语言,即有一些运算符,关键字ets。所有这些都被称为语法。
XSD(即W3C)的作者决定不发明另一种语法, 但要使用XML本身。因此,XSD以XML表示。 XML 是运营商。
基本上,这是一种巧合。为方便起见,XSD作者选择了它 (确实存在这种便利!)。 但是,这不是必要的要求。例如,还有另一种称为 RELAX NG 的XML模式语言,它不基于XML。
但是,一旦XML成为所有XSD文本的载体,您就必须处理特定于XML的事物,xmlns
就是其中之一。基本上,它为给定XML文件的元素分配默认命名空间。它与恰好在该文件中描述的XML模式无关。它只是该XML文件的惯例(无论它包含什么)。
targetNamespace
是XSD语言本身的东西。
它指定架构描述的XML元素属于哪个命名空间。
确实targetNamespace
和xmlns
之间存在一些冗余。
但是没有办法使用(利用)它,以便消除其中一个。试想一下:
XML将被XML解析器解析并转换为其他内容(例如 XML信息集)。这样的解析器不需要知道任何关于XSD的信息,它的输出也不是XML。因此,所有特定于XML的内容都将丢失(即xmlns
,名称空间前缀等)。
然后,将该信息集(或其他内容)传递给XSD处理器,该处理器从新开始,并且必须具有所有必要的信息。因此,targetNamespace
将是唯一告诉它关于该XML模式的目标命名空间的事情!
答案 1 :(得分:5)
模式定义了一组类型,元素,属性等。如果指定了 targetNamespace 属性,则在特定名称空间中定义这些组件,如果是空命名空间(或没有名称空间),则定义在这些组件中。没有 targetNamespace 属性。因此, targetNamespace 对于目标XML文档的语义至关重要:元素是否存在于某个命名空间中?
架构中的 xmlns 属性或多或少是一种方便的东西,在目标文档的语义方面没有任何意义。如何引用模式中的数据类型和组件会产生影响。
考虑这两种选择。在第一种替代方案中,默认命名空间与目标命名空间相同。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/animal" xmlns="http://www.example.com/animal"
elementFormDefault="qualified">
<xsd:simpleType name="Animal">
<xsd:restriction base="string">
<xsd:enumeration value="Dog" />
<xsd:enumeration value="Cat" />
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="animal" type="Animal" />
<xsd:element name="date" type="xsd:dateTime" />
</xsd:schema>
在第二种方法中,默认命名空间与XML Schema命名空间相同。请注意类型引用是如何“反转”的。
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/animal"
xmlns:tns="http://www.example.com/animal" elementFormDefault="qualified">
<simpleType name="Animal">
<restriction base="string">
<enumeration value="Dog"/>
<enumeration value="Cat"/>
</restriction>
</simpleType>
<element name="animal" type="tns:Animal" />
<element name="date" type="dateTime" />
</schema>
然而,无论替代方案如何,&lt; animal&gt;和&lt; date&gt;生活在http://www.example.com/animal
命名空间中。文件
<animal xmlns="http://www.example.com/animal" />
woudl对于bothalternatives有效。
答案 2 :(得分:3)
如果考虑两个简单的示例,targetNamespace和默认命名空间声明(xmlns=...
)之间的区别可能会变得更加清晰。第一:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/ns"
xmlns:tns="http://example.com/ns"
xmlns:ns2="http://example.com/ns2"
elementFormDefault="qualified">
<xs:import namespace="http://example.com/ns2"/>
<xs:complexType name="T1"/>
<xs:element name="doc" type="tns:T1"/>
<xs:element name="note" type="ns2:T1"/>
</xs:schema>
这里没有什么复杂的:架构文档声明了一个复杂类型和两个元素,都在目标命名空间http://example.com/ns中。由于它们位于命名空间中,因此任何引用元素声明或类型定义的文档都需要使用命名空间限定名称。
两个元素声明各自引用一个类型;两种类型都有本地名称T1,但它们位于不同的名称空间中,因此限定名称tns:T1和ns2:T1不同。
第二个示例声明完全相同的元素和类型,但在声明中使用略有不同的XML语法:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/ns"
xmlns="http://example.com/ns"
xmlns:ns2="http://example.com/ns2"
elementFormDefault="qualified">
<xs:import namespace="http://example.com/ns2"/>
<xs:complexType name="T1"/>
<xs:element name="doc" type="T1"/>
<xs:element name="note" type="ns2:T1"/>
</xs:schema>
唯一的区别是命名空间http://example.com/ns被声明为默认命名空间(使用xmlns =“http://example.com/ns”),因此doc
的元素声明可以使用一个非限定名称,用于引用该命名空间中的类型T1。
默认命名空间可以很容易地成为http://example.com/ns2 - 或者(如@ forty-two提供的一个示例中所示)http://www.w3.org/2001/XMLSchema。
当您了解这两个示例如何工作时,您将了解targetNamespace属性和默认命名空间声明如何相互关联(以及为什么不相关)。