【问题标题】:targetNamespace and xmlns目标命名空间和 xmlns
【发布时间】:2013-08-27 21:34:11
【问题描述】:

页面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?

【问题讨论】:

    标签: xml xsd xml-namespaces


    【解决方案1】:

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

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

    XSD(即 W3C)的作者决定不再发明另一种语法, 但为此使用 XML 本身。因此,XSD 是用 XML 表示的。 XML 是它的载体

    本质上,这是一种巧合。为方便起见,XSD 作者选择了它 (而且这种便利确实存在!)。 但是,这不是必要的要求。例如,还有另一种名为 RELAX NG 的 XML 模式语言,它不是基于 XML。

    但是一旦 XML 成为所有 XSD 文本的载体,您就必须处理特定于 XML 的事情,xmlns 就是其中之一。基本上,它为给定 XML 文件的元素分配默认命名空间。它与恰好在该文件中描述的 XML 模式无关。它只是那个 XML 文件的约定(不管它包含什么)。

    targetNamespace 相反,是 XSD 语言本身的东西。 它指定模式描述的 XML 元素将属于哪个命名空间。

    targetNamespacexmlns 之间确实存在一些冗余。 但是没有办法使用(利用)它,从而消除其中之一。想一想:

    XML 将被 XML 解析器解析并转换为其他内容(例如 XML 信息集)。这样的解析器不需要了解有关 XSD 的任何信息,并且它的输出不会是 XML。因此,所有 XML 特定的东西都将丢失(即xmlns、命名空间前缀等)。

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

    【讨论】:

    • 感谢您的回答。听起来像是我正在寻找的东西,但还不能确定。 XSD 新手。过一天再写。
    【解决方案2】:

    架构定义了一组类型、元素、属性等。如果指定了 targetNamespace 属性,则这些组件定义在特定命名空间中,如果指定了属性,则定义在空命名空间(或无命名空间)中没有 targetNamespace 属性。因此,targetNamespace 对于目标 XML 文档的语义至关重要:元素是否存在于某个命名空间中?

    schema 中的 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>
    

    但是,无论选择哪种方式, 都位于 http://www.example.com/animal 命名空间中。文件

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

    对两种选择都有效。

    【讨论】:

    • 感谢您的回答。听起来像是我正在寻找的东西,但还不能确定。 XSD 新手。过一天再写。
    【解决方案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 属性和默认命名空间声明如何相互关联(以及为什么不关联)。

    【讨论】:

    • 我明白了,targetNamespace 是特定于 XSD 的,它将确定架构中声明的类型将在哪个命名空间中,xmlns 是特定于 XML 的,用于为 xml 元素指定默认命名空间。
    • 没有。 targetNamespace 属性指定模式文档中声明的所有顶级元素、属性和类型的名称的名称空间部分; xmlns 属性指定如何解释无前缀名称。
    • 所以基本上xmlns 就像一个“导入”,使用现有的命名空间而targetNamespace 定义了一个(新的)命名空间?
    • @dasKeks - 嗯,不,这些不是我会使用的词,也不是大多数人使用的词。 xmlns="..." 形式的命名空间声明确定 XML 解析器如何解释出现在其范围内的无前缀名称,就像 xmlns:foo="..." 确定它们如何解释带有前缀 foo 的名称一样。命名空间声明可以在任何 XML 文档中使用。 XSD xsd:schema/@targetNamespace 属性为架构文档中声明或定义的所有顶级元素和类型指定命名空间名称。
    猜你喜欢
    • 2011-08-08
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    相关资源
    最近更新 更多