我正在尝试了解XSD架构。我无法发布原始架构,但有点如下。 我遇到的问题是我不明白为什么同一名称空间(http://www.test.com/test)被引用两次,一次使用前缀,一次不带前缀。这有效吗?如果是的话,它的用途是什么?
此外,在为此XSD生成XML时,我是否会使用前缀?
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com/test"
xmlns:pre="http://www.test.com/test" targetNamespace="http://www.test.com/test"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="StudentType">
<xs:sequence>
<xs:element name="studentId" type="xs:token" />
<xs:element name="firstName" type="xs:token"/>
<xs:element name="middleName" type="xs:token" minOccurs="0"/>
<xs:element name="lastName" type="xs:token"/>
</xs:sequence>
</xs:complexType>
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element name="student" type="StudentType" minOccurs="0" maxOccurs="unbounded">
<xs:unique name="uniqueStudentId">
<xs:selector xpath="pre:studentId"/>
<xs:field xpath="."/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
答案 0 :(得分:3)
这种事情在XSD中很常见。
targetNamespace定义架构文档中定义的顶级元素,类型等的名称空间。这些声明的“name”属性是一个本地名称(它不能加前缀),定义关联命名空间的唯一方法是使用targetNamespace声明。
xmlns =“http://www.test.com/test”声明影响未加前缀的名称引用,例如type =“StudentType”:这隐式地引用了具有本地名称“StudentType”的类型“在命名空间中”http://www.test.com/test“。
xmlns:pre =“http://www.test.com/test”声明会影响带有显式前缀“pre”的名称引用。这是必需的,因为模式包含xs:selector和xs:field中的XPath表达式。 XPath规范说如果没有前缀,则名称引用无名称空间中的名称,因此引用名称空间中名称的唯一方法是分配前缀。
因此,您有三个声明会影响架构文档中出现的各种名称。
答案 1 :(得分:2)
没有前缀的名称空间成为默认名称空间,因此它下面的所有元素都自动属于该名称空间,除非它们的显式限定条件不同。
现在是带前缀的命名空间 - 我看不出有什么理由不应该被允许。至于它的目的,我不确定,但我猜它可能与层次结构中其他重写命名空间的可能性有关?
我想再次强调这是猜测,但想象你有这样的事情:
<root xmlns="http://my.default.ns" xmlns:def="http://my.default.ns">
<class id="1">
<student>
This will automatically belong to https://my.default.ns
</student>
</class>
<class id="2" xmlns="http://especially.bright.pupils">
<student>
This will belong to http://especially.bright.pupils
</student>
<def:student>
NOTE: THIS student should still belong to https://my.default.ns,
since the element prefix relates to the namespace in the root element,
which has not been overridden. The DEFAULT namespace (without prefix),
has been overridden at this point, by the namespace defined in the
second <class>-element.
</def:student>
</class>
</root>
在这里,使用<def:student>
明确命名“默认”学生会阻止它被下面的新默认命名空间覆盖。
请注意,如果在下面重新定义xmlns:def
,它仍然可以被覆盖 - 它不会被默认命名空间覆盖。
更新以回复以下评论(希望我能正确理解您的问题):
命名空间本身由URI定义,因此它是相同的命名空间;这两个对这个命名空间的引用的作用是明确指定:
http://www.test.com/test
(即除非它们被覆盖,或者有一些链接到不同命名空间的前缀)pre:
的元素将属于命名空间http://www.test.com/test
换句话说,这些是两个(完全有效的)名称空间声明,恰好引用相同的名称空间。
请记住,名称空间本质上只是名称,用于排序/组织可能看起来相同的内容。
至于 TargetNamespaces 的目的,请参阅this question。