为什么我们需要targetNamespace?

Stu*_*ent 50 xml xsd namespaces

我想了解在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>
Run Code Online (Sandbox Code Playgroud)

为什么例如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模式,它们都是引用相同模式的契约,而不仅仅是包含相似但彼此不相同的元素的模式. .

这有任何意义吗 ?

Kev*_*vin 17

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

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

我认为你假设的是实例文档可以使用xsi:schemaLocation指定在某个模式文档中声明的元素和属性的命名空间.这不起作用.首先,解析器可以找到除列出的那些之外的其他模式文档,并且需要知道它们用于什么命名空间.另一个原因是,它将使推理模式很难或不可能的:你不能看一个模式,并知道这一切都是属于,因为这一决定将被推迟到实例写的命名空间.


pau*_*sm4 14

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

答:是的,确切地说.

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

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

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

...

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

澄清:

  • XML Schemas的主要目的是声明"词汇表".

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

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

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

'希望有所帮助

  • 顺便说一句!那里的解释非常好 (2认同)

jry*_*uer 11

我认为同时查看实例文档和模式文档有助于理解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>
Run Code Online (Sandbox Code Playgroud)

没有为文档指定默认名称空间,但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>
Run Code Online (Sandbox Code Playgroud)

<?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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

使用模式/实例,您有:

架构:

targetNamespace="http://localhost:8080/scribble/xml/Person"
targetNamespace="http://localhost:8080/scribble/xml/Vehicle"
Run Code Online (Sandbox Code Playgroud)

例如:

xmlns:p="http://localhost:8080/scribble/xml/Person"
xmlns:v="http://localhost:8080/scribble/xml/Vehicle"
Run Code Online (Sandbox Code Playgroud)

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

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

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


Mic*_*Kay 5

我不清楚你到底在问什么。显然,模式可以包含许多不同名称空间中的组件定义,并且必须有某种方式来表示“这是名称空间 N 中元素 E 的声明”。XSD 的设计者选择设计该语言,以便一个模式文档中的所有声明都属于同一名称空间,称为模块的目标名称空间。它可以有不同的包装,但差异将是非常表面的。您认为将模块与名称空间对齐的决定到底有什么问题?