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

时间:2011-08-25 12:44:30

标签: xml xsd schema xml-namespaces prefix

在xml架构文档中,如果我同时拥有targetNamespace和xmlns 而没有前缀

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

它们之间的确切区别是什么?我的理解是,如果你有一个没有前缀的xmlns,那么没有前缀的所有元素都会得到那个名称空间,而且...对于targetNamespace来说也是一样的。

6 个答案:

答案 0 :(得分:76)

targetNamespace 是一个XML Schema“artifact”;其目的:指示模式文件描述的特定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命名空间,在这种情况下它就意味着。从根本上说,它是一种避免命名冲突的机制;尽管如此,它也是一种在主题领域划分模型等的机制。

答案 1 :(得分:18)

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

首先,xsd就像上面发布的一样。它使用前缀&#39; xsd&#39;对于schema命名空间,以及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>  

...最后,使用默认命名空间而不是&#39; xsd&#39;对于XML架构命名空间:

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

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

答案 2 :(得分:14)

<强>的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

答案 3 :(得分:3)

  

名称空间意味着范围

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:p是QNames,xmlns是本地名称。

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

unordered

答案 4 :(得分: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用于在{ {1}}文件。

一旦创建了工件(或.xsd文件),您将在以下其他项目中使用它-

在Java项目中,您可以按以下方式使用.xsd(或pom.xml)文件导入库-

build.gradle

在XML中,您将使用

“导入”模式
    <dependency>
       <groupId>com.furniture</groupId>
       <artifactId>furniture-apis</artifactId>
       <version>1.1.1</version>
    </dependency>

===附录===

说明-

  1. <furniture xmlns="http://furniture.com"/> 既用作xmlns语句,也用作Java中的package语句。在import文件中,.xsd充当“ xmlns”语句,而在package文件中,它充当“ .xml”语句。

答案 5 :(得分:-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 =&#34; 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 =&#34; EGboy:recipeType&#34; 。我们不能再依赖 xmlns ,因为它具有不同的值,因此我们必须在 recipeType 前加上前缀 EGboy

xml文档甚至不关心 EGboy 前缀这个前缀仅供模式引用正确的 xmlns 以防万一。