xml 为什么我们需要 targetNamespace?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9853484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 15:16:50  来源:igfitidea点击:

Why do we need targetNamespace?

xmlnamespacesxsd

提问by Student

I would like to understand the purpose of targetNamespace as used both in XML Schema and in WSDL. In fact, to keep things simple, let's limit this question to XML Schema.

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

I feel like I fully understand the notion of (simple) XML namespaces. By convention we use URI/URLs, but we could use any string, which we then assign to a prefix for reuse by XML nodes and attributes, or use simply as the default namespace for the scope at hand. So far, so good ?

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

Now enters XML Schema. For some reason the inventors of XML Schema felt the notion of simple namespaces wasn't enough and they had to introduce the targetNamespace. My question is : what significant benefit does a targetNamespace introduce that couldn't be provided by a normal XML namespace ? If an XML document references a xsd document, either by schemaLocation or with an import statement, in either case I give the path to the actual xsd document being referenced. This is what uniquely defines the Schema I want to refer to. If in addition I want to bind this Schema to a particular namespace in my referencing document, why should I be obliged to replicate the precise targetNamespace already defined in the XML Schema I am referencing? Why couldn't I simply redefine this namespace however I want within the XML document in which this namespace will be used to refer to that particular XML Schema document I want to reference ?

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

Update:

更新:

To give an example, if I have the following in an XML instance document:

举个例子,如果我在 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>

Why does e.g. the people.xsd Schema need to define a targetNamespace which is "http://contoso.com/schemas/People"? Why do we need the targetNamespace definition in the xsd document at all? It seems to me all you have to gain from the namespace part of the schemaLocation is already contained in the XML instance document. What is the benefit of enforcing the existence of a targetNamespace with equal value over in the xsd document ?

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

Follow-up question to Paul's answer:

保罗回答的后续问题:

Can you give me a concrete example where such "clashes" between xsd element names becomes apparent and that would explain the need for targetNamespace ?

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



Ok, here's an attempt to answer my own question. Let me know if it seems coherent to you. Looking at the examples on the page linked by Paul helped me.

好的,这是尝试回答我自己的问题。让我知道它是否对你来说是一致的。查看 Paul 链接的页面上的示例对我有帮助。

If we take the XML instance example in the original question above, we have two references to the definition of the vehicle element. One is explicit and visible in the XML instance document itself, but we must also imagine that the person.xsd XML Schema references the same vehicle definition again as an allowed child element of person. If we were to use normal namespaces where each document were allowed to define its own namespace for vehicle, how would we know that the XML instance is referencing the same XML Schema definition for vehicle as is the person.xsd ? The only way is by enforcing a concept of namespace which is stricter than the original simple one and which must be written exactly the same way across multiple documents.

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

If I wasn't writing this on a tablet I would provide a code example, but here I will just attempt to describe the example I have in mind.

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

Imagine that we have two different XML Schema definitions for a vehicle element. location1/vehicles.xsd would contain the definition that validates the example from the question of this post (containing color, wheels, and seats child elements), whereas location2/vehicles.xsd would contain an entirely different definition for a vehicle element, (say, with child elements year, model, and volume). Now, if the XML instance document refers to the location1 Schema, as is the case in the example above, but person.xsd says that the person element can contain a vehicle child element of the type defined in the location2 Schema, then without the notion of a targetNamespace, the XML instance would validate, even though it clearly doesn't have the right kind of vehicle as a child element of its person element.

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

Target namespaces then help us make sure that if two different documents are referencing the same third XML Schema, that they are both in deed referencing the same Schema and not just a Schema that contains elements that are similar, but not identical to one another...

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

Does that make any sense ?

这有任何意义吗 ?

回答by Kevin

You seem to be on the right track. I'll make a few points here that might help.

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

  • Within an instance document, you use XML namespaces to identify the namespace that an element or attribute is in.
  • Within a schema document, you declare elements and attributes that will appear in instances. What namespace are they declared to be in? This is what targetNamespace is for.
  • The schema document location and the namespace are not the same thing. It is quite common to have multiple .xsd documents with the same targetNamespace. (They may or may not include each other, but typically will include each other.)
  • Instance documents do not always have an xsi:schemaLocation element to tell parsers where to locate the schemas. Various methods may be used to tell a parser where to locate relevant schema documents. An XSD may be located on local disk or at some web address and this should not affect the namespace of the elements in it.
    • xsi:schemaLocation is a hint. Parsers may locate the schema for the given namespace elsewhere, which implies that they must be able to know what namespace a schema is for.
    • Tools, such as databinding tools, will precompile schemas and produce code that recognizes valid documents. These must be able to know the namespaces of the declared elements.
  • 在实例文档中,您使用 XML 名称空间来标识元素或属性所在的名称空间。
  • 在模式文档中,您声明将出现在实例中的元素和属性。它们声明在什么命名空间中?这就是 targetNamespace 的用途。
  • 架构文档位置和命名空间不是一回事。多个 .xsd 文档具有相同的 targetNamespace 是很常见的。(它们可能相互包含也可能不包含,但通常会相互包含。)
  • 实例文档并不总是有一个 xsi:schemaLocation 元素来告诉解析器在哪里定位模式。可以使用各种方法来告诉解析器在哪里可以找到相关的模式文档。XSD 可能位于本地磁盘或某个 Web 地址上,这不应影响其中元素的命名空间。
    • xsi:schemaLocation 是一个提示。解析器可以在别处定位给定命名空间的模式,这意味着它们必须能够知道模式用于哪个命名空间。
    • 数据绑定工具等工具将预编译模式并生成识别有效文档的代码。这些必须能够知道声明元素的命名空间。

I think what you were assuming is that the instance document could specify the namespace of the elements and attributes declared in some schema document, using xsi:schemaLocation. That doesn't work. For one thing, the parser may locate other schema documents than those listed, and it needs to know what namespace they are for. For another, it would make reasoning about schemas difficult or impossible: you wouldn't be able to look at a schema and know the namespaces that everything belonged in because that decision would be postponed until an instance was written.

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

回答by paulsm4

Q: "By convention we use URI/URLs, but we could use any string, which we then assign to a prefix for reuse by XML nodes and attributes, or use simply as the default namespace for the scope at hand."

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

A: Yes, exactly.

答:是的,没错。

Q: "For some reason the inventors of XML Schema felt the notion of simple namespaces wasn't enough and they had to introduce the targetNamespace."

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

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

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

Breaking schemas into multiple files can have several advantages. You can create re-usable definitions that can be used across several projects. They make definitions easier to read and version as they break down the schema into smaller units that are simpler to manage.

...

This all works fine without namespaces, but if different teams start working on different files, then you have the possibility of name clashes, and it would not always be obvious where a definition had come from. The solution is to place the definitions for each schema file within a distinct namespace.

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

...

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

Clarification:

澄清:

  • The primary purpose of XML Schemas is to declare "vocabularies".

  • These vocabularies can be identified by a namespace that is specified in the targetNamespace attribute.

  • The Schema (an XML document) can have a "namespace". The "vocabulary" the document describes can have a "targetNamespace".

  • Just as XML Schemas provide a higher level of abstraction than SGML DTD's (the original architects of XML thought DTD's were sufficient), XML Schema "targetNamespaces" provide a level of abstraction over "simple namespaces".

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

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

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

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

'Hope that helps

'希望有帮助

回答by jrypkahauer

I think it helps to look at both the instance document and the schema document at the same time to understand what targetNamespace does. Consider this (based on your instance document):

我认为同时查看实例文档和模式文档有助于理解 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>

There's no default namespace specified for the document, but p:* and v:* are aliased to specific NS URIs. Now take a look at the schema document itself:

没有为文档指定默认命名空间,但 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>

and

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

If you look at the attributes on the tags, the default namespace is "http://www.w3.org/2001/XMLSchema" for both the schema documents... but the targetNamespace is the one used as the aliased namespace in the instance document.

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

targetNamespace is the expected namespace of the instances regardless of the namespace of the schema documents and any other namespace specified in the instance document.

targetNamespace 是实例的预期名称空间,而不管模式文档的名称空间和实例文档中指定的任何其他名称空间。

I find it kind of helpful to think of it like hosting a party where you have a guest list and guests wearing name-tags. Think of the targetNamespace in the schema documents like the names on the guest list. The xmlns, aliased or not, in the instance documents is like the name-tags on the guests. As long as you have the guest list (which miraculously includes a photocopy of their state-issued ID), whenever you encounter someone you can validate their identity. If you come across someone wearing a name-tag that doesn't match the attached parameters, you can freak out (i.e. throw an error).

我觉得把它想象成举办一个有客人名单和戴着名牌的派对会很有帮助。将模式文档中的 targetNamespace 想象为来宾列表中的名称。实例文档中的 xmlns,无论是否别名,就像来宾上的名称标签。只要你有客人名单(其中奇迹般地包括了他们国家颁发的身的复印件),无论何时你遇到某人,你都可以验证他们的身份。如果您遇到佩戴与附加参数不匹配的名牌的人,您可能会惊慌失措(即抛出错误)。

With the schema/instances, you have:

使用架构/实例,您有:

Schemas:

架构:

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

Instance:

实例:

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

Or... any guest nicknamed "v" that you encounter anywhere in the party (barring special rules that say otherwise), any floor of the house or in the backyard or in the pool, better match the description for a guest on the guest list named http://localhost:8080/scribble/xml/Vehicle. or they're an intruder.

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

Those special rules may say something like, V can only hang out if they're immediately next to P, or P can only hang out if V is present. In this case, P has to hang when V is there, but V can go pretty much anywhere they want without A being there.

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

This way a schema can be incredibly flexible, defining pretty much any data structure desired and being able to track what goes where just by matching the namespaces (default or prefixed) of any given element back to the TNS and associated schema.

通过这种方式,模式可以非常灵活,几乎可以定义任何所需的数据结构,并且能够通过将任何给定元素的命名空间(默认或前缀)与 TNS 和关联模式进行匹配来跟踪数据的去向。

回答by Michael Kay

It's not clear to me exactly what you are asking. Clearly a schema can contain definitions of components in many different namespaces, and there has to be some way of saying "This is a declaration of element E in namespace N". The designers of XSD chose to design the language so that all the declarations in one schema document belong to the same namespace, called the target namespace of the module. It could have been packaged differently, but the difference would be very superficial. What exactly do you think is wrong with the decision to align modules with namespaces?

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