xml - 为什么我们需要targetNamespace?




namespaces xsd (3)

问:“按照惯例,我们使用URI / URL,但我们可以使用任何字符串,然后我们将其分配给前缀以供XML节点和属性重用,或者仅用作手头范围的默认命名空间。”

答:是的,确切地说。

问:“出于某种原因,XML Schema的发明者认为简单命名空间的概念还不够,他们不得不引入targetNamespace。”

答: http://www.liquid-technologies.com/Tutorials/XmlSchemas/XsdTutorial_04.aspxhttp://www.liquid-technologies.com/Tutorials/XmlSchemas/XsdTutorial_04.aspx

将模式分解为多个文件可以有几个优点。 您可以创建可在多个项目中使用的可重用定义。 它们使定义更易于阅读和版本,因为它们将模式分解为更易于管理的较小单元。

...

这一切都可以在没有命名空间的情况下正常工作,但如果不同的团队开始处理不同的文件,那么你就有可能发生名称冲突,而且定义来自哪里并不总是很明显。 解决方案是将每个模式文件的定义放在不同的命名空间中。

澄清:

  • XML Schemas的主要目的是声明“词汇表”。

  • 这些词汇表可以通过targetNamespace属性中指定的命名空间来标识。

  • Schema(XML文档)可以具有“命名空间”。 文档描述的“词汇表”可以具有“targetNamespace”。

  • 正如XML Schema提供比SGML DTD更高级别的抽象(XML的原始架构师认为DTD已经足够),XML Schema“targetNamespaces”提供了对“简单命名空间”的抽象级别。

'希望有所帮助

我想了解在XML Schema和WSDL中使用的targetNamespace的目的。 实际上,为了简单起见,我们将这个问题限制为XML Schema。

我觉得我完全理解(简单)XML命名空间的概念。 按照惯例,我们使用URI / URL,但我们可以使用任何字符串,然后我们将其分配给前缀以供XML节点和属性重用,或者仅用作手头范围的默认命名空间。 到现在为止还挺好 ?

现在进入XML Schema。 出于某种原因,XML Schema的发明者认为简单命名空间的概念是不够的,他们不得不引入targetNamespace。 我的问题是:targetNamespace引入了哪些不能由普通XML命名空间提供的重要好处? 如果XML文档通过schemaLocation或import语句引用xsd文档,则在任何一种情况下,我都会给出要引用的实际xsd文档的路径。 这是唯一定义我想要引用的Schema的内容。 如果另外我想将此Schema绑定到我的引用文档中的特定命名空间,为什么我必须复制已在我引用的XML Schema中定义的精确targetNamespace? 为什么我不能简单地重新定义这个命名空间,但我想在XML文档中使用这个命名空间来引用我想引用的特定XML Schema文档?

更新:

举个例子,如果我在XML实例文档中有以下内容:

<p:Person
   xmlns:p="http://contoso.com/People"
   xmlns:v="http://contoso.com/Vehicles"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation=
    "http://contoso.com/schemas/Vehicles
     http://contoso.com/schemas/vehicles.xsd
     http://contoso.com/schemas/People
     http://contoso.com/schemas/people.xsd">
   <name>John</name>
   <age>28</age>
   <height>59</height>
   <v:Vehicle>
      <color>Red</color>
      <wheels>4</wheels>
      <seats>2</seats>
   </v:Vehicle>
</p:Person>

为什么例如people.xsd Schema需要定义一个“http://contoso.com/schemas/People”的targetNamespace? 为什么我们需要在xsd文档中定义targetNamespace? 在我看来,您必须从schemaLocation的名称空间部分获得的所有内容都已包含在XML实例文档中。 在xsd文档中强制存在具有相等值的targetNamespace有什么好处?

保罗回答的后续问题:

你能给我一个具体的例子,说明xsd元素名称之间的这种“冲突”变得明显,这可以解释对targetNamespace的需求吗?

好的,这是试图回答我自己的问题。 如果它对你来说似乎是连贯的,请告诉我。 查看保罗链接页面上的示例帮助了我。

如果我们在上面的原始问题中采用XML实例示例,我们有两个对车辆元素定义的引用。 一个在XML实例文档本身中是显式且可见的,但我们还必须想象person.xsd XML Schema再次引用相同的车辆定义作为person的允许子元素。 如果我们使用普通命名空间,其中允许每个文档为车辆定义自己的命名空间,我们如何知道XML实例引用车辆的相同XML模式定义,与person.xsd一样? 唯一的方法是强制执行命名空间的概念,该概念比原始的简单概念更严格,并且必须在多个文档中以完全相同的方式编写。

如果我不是在平板电脑上写这个,我会提供一个代码示例,但在这里我将尝试描述我想到的例子。

想象一下,我们为车辆元素提供了两种不同的XML Schema定义。 location1 / vehicles.xsd将包含从该帖子的问题验证示例的定义(包含颜色,轮子和座位子元素),而location2 / vehicles.xsd将包含完全不同的车辆元素定义,(比如说) ,包含子元素年份,型号和体积)。 现在,如果XML实例文档引用了location1 Schema,就像上面示例中的情况一样,但是person.xsd说person元素可以包含location2 Schema中定义的类型的vehicle子元素,那么没有概念对于targetNamespace,XML实例将验证,即使它显然没有正确类型的车辆作为其person元素的子元素。

目标命名空间然后帮助我们确保如果两个不同的文档引用相同的第三个XML模式,它们都是引用相同模式的契约,而不仅仅是包含相似但彼此不相同的元素的模式。 。

这有任何意义吗 ?


你似乎走在了正确的轨道上。 我会在这里提出几点可能有所帮助。

  • 在实例文档中,您使用XML命名空间来标识元素或属性所在的命名空间。
  • 在架构文档中,您声明将出现在实例中的元素和属性。 他们声称的名称空间是什么? 这就是targetNamespace的用途。
  • 架构文档位置和命名空间不是一回事。 具有相同targetNamespace的多个.xsd文档是很常见的。 (它们可能相互包含,也可能不相互包含,但通常会相互包含。)
  • 实例文档并不总是有一个xsi:schemaLocation元素来告诉解析器在哪里找到模式。 可以使用各种方法来告知解析器在何处定位相关的模式文档。 XSD可能位于本地磁盘或某个Web地址上,这不应影响其中元素的命名空间。
    • xsi:schemaLocation是一个提示。 解析器可以在其他地方找到给定命名空间的模式,这意味着它们必须能够知道模式的命名空间。
    • 诸如数据绑定工具之类的工具将预编译模式并生成识别有效文档的代码。 这些必须能够知道声明元素的名称空间。

我认为你假设的是实例文档可以使用xsi:schemaLocation指定在某个模式文档中声明的元素和属性的命名空间。 这不起作用。 首先,解析器可以找到除列出的那些之外的其他模式文档,并且需要知道它们用于什么命名空间。 另一方面,它会使模式的推理变得困难或不可能:您将无法查看模式并知道所有内容所属的名称空间,因为该决定将被推迟到实例写入之前。


我认为同时查看实例文档和模式文档有助于理解targetNamespace的作用。 考虑一下(基于您的实例文档):

<p:Person
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://localhost:8080/scribble/xml/Person"
        xmlns:v="http://localhost:8080/scribble/xml/Vehicle"
        xsi:schemaLocation="
            http://localhost:8080/scribble/xml/Person
            http://localhost:8080/scribble/xml/person.xsd">
    <name>John</name>
    <age>28</age>
    <height>59</height>
    <v:Vehicle>
        <color>Red</color>
        <wheels>4</wheels>
        <seats>2</seats>
    </v:Vehicle>
</p:Person>

没有为文档指定默认名称空间,但p:*和v:*是特定NS URI的别名。 现在看一下架构文档本身:

<?xml version="1.0" encoding="UTF-8"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://localhost:8080/scribble/xml/Person"
    elementFormDefault="qualified"
    xmlns:v="http://localhost:8080/scribble/xml/Vehicle">

    <import
        namespace="http://localhost:8080/scribble/xml/Vehicle"
        schemaLocation="http://localhost:8080/scribble/xml/v.xsd"/>

    <element name="Person">
        <complexType>
            <sequence>
                <element name="name" form="unqualified" type="NCName"/>
                <element name="age" form="unqualified" type="integer"/>
                <element name="height" form="unqualified" type="integer"/>
                <element ref="v:Vehicle"/>
            </sequence>
        </complexType>
    </element>

</schema>

<?xml version="1.0" encoding="UTF-8"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://localhost:8080/scribble/xml/Vehicle"
    elementFormDefault="qualified">

    <element name="Vehicle">
        <complexType>
            <sequence>
                <element name="color" form="unqualified" type="NCName"/>
                <element name="wheels" form="unqualified" type="integer"/>
                <element name="seats" form="unqualified" type="integer"/>
            </sequence>
        </complexType>
    </element>
</schema>

如果查看标记上的属性,那么两个模式文档的默认命名空间都是“ http://www.w3.org/2001/XMLSchema ”...但是targetNamespace是用作别名命名空间的名称空间。实例文件。

targetNamespace是实例的预期命名空间,无论架构文档的命名空间和实例文档中指定的任何其他命名空间如何。

我觉得将它想象为举办一个有客人名单的聚会以及带名字标签的客人会有所帮助。 可以考虑架构文档中的targetNamespace,例如guest列表中的名称。 实例文档中的xmlns,别名或非别名,就像guest虚拟机上的名称标签一样。 只要你有客人名单(奇迹般地包括他们国家颁发的身份证复印件),无论何时遇到某人你都可以验证他们的身份。 如果您遇到名称标签与附加参数不匹配的人,您可能会惊慌失措(即抛出错误)。

使用模式/实例,您可以:

架构:

targetNamespace="http://localhost:8080/scribble/xml/Person"
targetNamespace="http://localhost:8080/scribble/xml/Vehicle"

例如:

xmlns:p="http://localhost:8080/scribble/xml/Person"
xmlns:v="http://localhost:8080/scribble/xml/Vehicle"

或者......任何昵称为“v”的客人,您在聚会中的任何地方都会遇到这种情况(除非另有规定,否则特殊规则),房屋的任何楼层或后院或游泳池中的客人都会更好地与客人的描述相符列表名为http://localhost:8080/scribble/xml/Vehicle 。 或者他们是入侵者。

这些特殊规则可能会说,如果它们紧挨着P,则V只能挂出,或者如果V存在,则P只能挂出。 在这种情况下,当V在那里时P必须挂起,但是V可以在他们想要的任何地方进行,而不是A在那里。

这样,模式可以非常灵活,几乎可以定义任何所需的数据结构,并且能够通过将任何给定元素的名称空间(默认或前缀)与TNS和关联模式相匹配来跟踪其中的内容。





xsd