targetNamespace和xmlns不带前缀,有什么区别?


76

在xml模式文档中,如果我同时具有targetNamespace和xmlns而不带前缀

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://example.com/" xmlns="http://example.com/">

它们之间的确切区别是什么?我的理解是,如果您有一个不带前缀的xmlns,则所有不带前缀的元素都将获得该名称空间,并且...对targetNamespace来说同样令人困惑。


1
我可能对此主题缺乏知识,但是答案不只能是:xmlns是THIS文档(架构文档)的默认名称空间,而targetNamespace是此架构文档验证的名称空间吗?以这种方式xmlns和targetNamespace是两个不同的东西吗?
Vering 2016年

@Vering我的测试结果与您的第一句话一致,是的,targetNamespace绝对是指架构验证的文档。targetNamespace的存在似乎也需要'xmlns'或'xmlns:xxx'的存在。实际上,您可以将许多'xmlns:xxx','xmlns:yyy'和'xmlns'组合在一起,并且仍然可以验证。
eigenfield'3

Answers:


80

targetNamespace是一个XML模式“工件”;它的目的:指示模式文件描述什么特定的XML名称空间。

xmlns- 因为XML Schema是XML文档,所以可以为XML文件本身定义默认的XML命名空间(这是xmlns属性的作用);其含义是多重的:创作和合成。例如,不必为模式中定义的项使用前缀,这些项以后会在同一文件的其他位置引用(例如,用作属性或元素类型的全局simpleType)。

根据我的经验,许多XML Schema作者认为这是“最佳实践”……因此您处在正确的道路上。

就XSD而言,targetNamespace规定了模式组件合格名称的名称空间部分,该名称包括元素,属性,组和属性组以及简单和复杂类型。XSD中定义的某些合格名称(元素和属性)由XML实例文档“直接”使用。其他类型(例如类型)可以通过实例XML文档中的xsi:type属性进行引用。其余的(组,属性组)在那里(通过引用)促进架构组合。

我还认为,(通常)人们从两个角度来设计XSD:

  • 匹配现有的XML。在这种情况下,如果XML使用名称空间,则对于每个使用的名称空间,您将最终获得带有匹配targetNamespace属性的XSD模式元素。

  • 纯建模。然后,您会想到targetNamespace类似于UML包,数据库模式,Java包或.NET名称空间,在这种情况下,这意味着所有这些。从根本上说,这是一种避免命名冲突的机制。尽管如此,它还是一种在主题区域等中划分模型的机制。


28

对于仍然感到困惑的人,请考虑这三个xsds。它们都定义了一个全局类型和一个引用它的全局元素定义。

首先,像上面发布的那样一个xsd。它为模式名称空间使用前缀“ xsd”,并为targetNamespace使用默认名称空间:

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns="http://example.com/">

  <xsd:element name="aGlobalElement" type="aGlobalType"/>

  <xsd:simpleType name="aGlobalType">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>   
</xsd:schema>  

现在是相同的xsd,但为目标名称空间定义并使用名称空间前缀:

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns:tns="http://example.com/">

  <xsd:element name="aGlobalElement" type="tns:aGlobalType"/>

  <xsd:simpleType name="aGlobalType">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType> 
</xsd:schema>  

...最后是使用默认名称空间而不是XML模式名称空间的'xsd'的版本:

<schema 
  xmlns="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns:tns="http://example.com/">

  <element name="aGlobalElement" type="tns:aGlobalType"/>

  <simpleType name="aGlobalType">
    <restriction base="string"/>
  </simpleType>
</schema>

大多数模式作者选择第一个或最后一个,因为如果默认名称空间工具可用,那么我们也可以将其用于某些东西


15

xmlns

xmlns属性设置所描述元素的默认名称空间。因此,默认名称空间将应用于所描述元素内部的所有元素,这些元素不会为自己明确声明另一个名称空间。

WSDL文件的默认名称空间设置为标准值:http : //www.w3.org/ns/wsdl

targetNameSpace

此属性包含Web服务的名称空间。您可以自由选择此名称空间,但是有一个约定说URI应该指向服务的WSDL。

xmlns:tns

此名称空间应设置为与targetNameSpace属性相同的URI。这样,您可以通过此名称空间前缀(tns)引用目标名称空间。

资料来源:http : //tutorials.jenkov.com/wsdl/description.html


targetNamespace的URI不会“指向”任何东西-只是命名空间的标识符。它可能是Web服务的URI,但仍仅用于标记名称空间。
Suncat2000

4

命名空间意味着范围

targetNamespaceschema元素的属性,用于定义名称空间,即XSD文件中的包。按照惯例,我们使用URI / URL,但是我们可以使用任何字符串。

xmlns 是一个属性,用于引用当前元素范围的xmlns属性值中的元素和数据类型。

例如:

  • xmlns:xsd="http://www.w3.org/2001/XMLSchema"是带前缀的,这xsd意味着名称空间应以xsd:
  • xmlns="http://www.w3.org/2001/XMLSchema" 默认不带前缀
  • xmlns:p =“ http://www.example.com/People”带有前缀,因为p名称空间应带有前缀p:

其中xmlns:xsdxmlns:pQNames和xmlns是本地名称。

根据我的知识,下图有助于理解使用Java类比的XSD:

在此处输入图片说明


1

其他答案在这里很好,因此在此我将不再重复其解释。但是,如果有Java背景的人发现它更简单,这就是我想出的类比-

  1. .xsd文档是工件/.jar文件
  2. xmlns 是个

    package com.example
    

    语句,您在Java类的顶部声明。

考虑一下(类比),如果您的Java项目中只有一个包,并且所有类都在一个外部类中声明和定义 例如

    package com.furniture.models

    public class FurnitureShop {

         int noOfTables;
         int noOfChairs;
         int noOfBeds;
         List<Table> tables;
         List<Chair> chairs;
         List<Bed> beds;

         // and now instead of declaring and defining a class for table/chair/bed in a 
         // separate file, you just add it here 
         public static class Table {
             int height;
             int width;
             int length;
             ...
         }

         public static class Chair {
             String color;
             ChairType chairType;
             ...
         }

         public static class Sofa {
             int price;
             String color;
             ...
         }
    }

这就是将不同元素组合到一个.xsd文件中以形成新架构的方式。

  1. targetNamespace是您创建的工件的名称正如您自己发现的那样,targetNamespace在创建模式时.xsd文件中使用它。

一旦.xsd创建了工件(或文件),就可以在其他项目中使用它,如下所示-

在Java项目中,您将使用pom.xml(或build.gradle)文件导入库,如下所示-

    <dependency>
       <groupId>com.furniture</groupId>
       <artifactId>furniture-apis</artifactId>
       <version>1.1.1</version>
    </dependency>

在XML中,您可以使用

    <furniture xmlns="http://furniture.com"/>

===附录===

澄清-

  1. xmlns既用作package语句,也用作importJava中的语句。在.xsd文件中,xmlns充当“ package”语句,而在.xml文件中,充当“ import”语句。

-1

在使用xmllint进行了彻底的测试之后,我想我在这里找到了明确的解释。考虑以下架构:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://yyyzzz.com"
xmlns:p="http://abced.com"
xmlns:q="http://pqr.com"
xmlns="http://yyyzzz.com">

<xsd:element name="recipe" type="recipeType" />

<xsd:complexType name="recipeType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
        <xsd:attribute name="desc" type="xsd:string"  />
        <xsd:attribute name="archetype" type="xsd:string" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>
</xsd:schema>

以上架构可验证以下文档:

<?xml version="1.0"?>

<recipe xmlns="http://yyyzzz.com">
    Deciphering the purpose of targetNamespace
</recipe>

起作用的原因是因为xmlns =“ http://yyyzzz.com”也自动绑定到架构所定义的元素!这就是说,它也绑定到recipeType元素。

现在,使用相同的xml文档,但具有如下所示的略微修改的架构,也可以验证并仔细观察它们之间的区别:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://yyyzzz.com"
xmlns="http://eigenfield.aparicio.com"
xmlns:EGboy="http://yyyzzz.com">

<xsd:element name="recipe" type="EGboy:recipeType" />

<xsd:complexType name="recipeType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
        <xsd:attribute name="desc" type="xsd:string"  />
        <xsd:attribute name="archetype" type="xsd:string" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

</xsd:schema> 

忽略其他xmlns是否丢失,而是仔细查看type =“ EGboy:recipeType”。我们不能再依靠的xmlns,因为它有不同的价值,因此,我们必须把前缀EGboy前面recipeType

xml文档甚至不关心EGboy前缀。此前缀仅用于架构在存在许多xmlns的情况下引用正确的xmlns

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.