4

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对我来说是多余的,因为它们指的是同一个命名空间。

我错过了什么?

注意:我已经看到XML 中的“xmlns”是什么意思?在其他一些讨论中。

4

3 回答 3

14

要了解 和 之间的区别targetNamespacexmlns请思考以下问题。

XSD是一种描述 XML 模式的语言。任何计算机语言都必须以某种方式表达,即具有一些运算符、关键字等。所有这些东西都称为语法。

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 infoset)。这样的解析器不需要了解有关 XSD 的任何信息,并且它的输出不会是 XML。因此,所有 XML 特定的东西都将丢失(即xmlns命名空间前缀等)。

然后,该信息集(或其他东西)被传递给 XSD 处理器,该处理器重新开始,并且它必须拥有所有必要的信息。因此,targetNamespace将是唯一告诉它该 XML 模式的目标名称空间的东西!

于 2013-08-27T22:25:47.357 回答
6

A schema defines a set of types, element, attributes, etc. These components are defined in a specific namespace if the targetNamespace attribute is specified, or in the empty namespace (or no namespace) if there are no targetNamespace attribute. Hence, the targetNamespace is essential to the semantics of your target XML documents: Do the elements live in a certain namespace or not?

The xmlns attribute in the schema is more or less a convenience thing and means nothing in terms of the semantics of your target documents. There are consequences in how you refer to data types and components within the schema.

Consider these two alternatives. In the first alternative the default namespace is the same as the target namespace.

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

In the second alternative, the default namespace is the same as the XML Schema namespace. Note how the type references are "inverted".

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

However, regardless of the alternative, both <animal> and <date> lives in the http://www.example.com/animal namespace. The document

<animal xmlns="http://www.example.com/animal" />

woudl be valid for bothalternatives.

于 2013-08-27T22:17:14.873 回答
4

xmlns=...如果考虑两个简单的示例,targetNamespace 和默认命名空间声明 ( ) 之间的区别可能会变得更加清晰。第一的:

<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/ XML 架构

当您了解这两个示例如何工作时,您将了解 targetNamespace 属性和默认命名空间声明如何相互关联(以及为什么不关联)。

于 2013-08-28T01:46:52.913 回答