在xml架构文档中,如果我同时拥有targetNamespace和没有前缀的xmlns。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/" xmlns="http://example.com/">
它们之间的确切区别是什么?我的理解是,如果你有一个没有前缀的xmlns,那么没有前缀的所有元素都会得到那个名称空间,并且......对于targetNamespace来说,这一点令人困惑。
targetNamespace是一个XML Schema“artifact”;其目的:指示模式文件描述的特定XML名称空间。
xmlns - 因为XML Schema是一个XML文档,因此可以为XML文件本身定义一个默认的XML命名空间(这是xmlns属性所做的);影响是多重的:创作和作曲。例如,一个人不必为模式中定义的项使用前缀,稍后在同一文件中的其他位置引用(例如,用作属性或元素的类型的全局simpleType)。
根据我的经验,许多XML Schema作者认为这是一种“最佳实践”......所以你走在了正确的轨道上。
就XSD而言,targetNamespace规定了模式组件的限定名称的名称空间部分,其中包括元素,属性,组和属性组以及简单和复杂类型。 XSD(元素和属性)中定义的某些限定名称由XML实例文档“直接”使用。其他的,例如类型,可以通过实例XML文档中的xsi:type属性引用。其余的(组,属性组)用于促进模式组合(通过引用)。
我也认为(一般来说)人们从两个角度来设计XSD:
对于仍然困惑的人,请考虑这三个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>
大多数模式作者选择第一个或最后一个,因为如果默认名称空间工具可用,那么我们也可以将它用于某些东西。
XMLNS
xmlns属性设置所描述元素的默认名称空间。因此,默认名称空间应用于所描述元素内的所有元素,这些元素不会为自己显式声明另一个名称空间。
默认名称空间设置为WSDL文件的标准值:http://www.w3.org/ns/wsdl
目标名称
此属性包含Web服务的名称空间。您可以自由选择此名称空间,但有一个约定,即URI应指向服务的WSDL。
的xmlns:TNS
此名称空间应设置为与targetNameSpace属性相同的URI。这样,您可以通过此名称空间前缀(tns)引用目标名称空间。
命名空间意味着范围
targetNamespace
是schema
元素的属性,定义了命名空间,即XSD文件中的包。按照惯例,我们使用URI / URL,但我们可以使用任何字符串。
xmlns
是一个属性,用于引用来自当前元素范围的xmlns属性值的元素和数据类型。
例如:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
带有前缀,因为xsd
表示名称空间应该以xsd:
为前缀xmlns="http://www.w3.org/2001/XMLSchema"
是默认的p
表示名称空间应该以p:
为前缀xmlns:xsd
和xmlns:p
是QNames,xmlns
是本地名称。
根据我的知识,下图有助于理解使用Java类比的XSD:
其他答案很好,所以我不会在这里重复他们的解释。但是,如果有人来自Java背景,发现它更简单,这就是我想出的类比 -
.xsd
文件是artifact / .jar
文件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
文件中的不同元素分组的方式。
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"/>
===附录===
澄清 -
xmlns
既被用作package
语句,也被用作Java中的import
语句。在.xsd
文件中,xmlns
充当“package
”声明,而在.xml
文件中,它充当“import
”声明。在使用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。