带有来自其他命名空间的元素的 XSD
Posted
技术标签:
【中文标题】带有来自其他命名空间的元素的 XSD【英文标题】:XSD with elements from other namespace 【发布时间】:2011-09-18 18:44:07 【问题描述】:我有两个定义不同文档的 XSD。比如说A.xsd
定义了一个元素ElementA
作为根,有一些复杂的规则。现在B.xsd
定义了一个元素ElementB
,它应该在两者之间使用ElementA
。
例如,我希望ElementB
的 XML 文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<ElementB xmlns="http://example.com/namespace/for/ElementB">
<foo>Bla</foo>
<bar>Blub</bar>
<ElementA xmlns="http://example.com/namespace/for/ElementA">
<!-- ... -->
</ElementA>
</ElementB>
那么B.xsd
可能看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://example.com/namespace/for/ElementB" targetNamespace="http://example.com/namespace/for/ElementB" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="ElementB">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="xs:string" />
<xs:element name="bar" type="xs:string" />
<!-- And now I want to include ElementA somehow -->
<xs:element name="ElementA" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
问题是我真的不想将ElementA
的规范克隆到B.xsd
,因为也有文档,只是以ElementA
作为根(即ElementB
是某种容器文件)。
那么,我怎样才能在ElementB
中允许ElementA
,同时完全建立在已经存在的XSD 之上?
【问题讨论】:
【参考方案1】:实际上有两种不同的方式来编写 XML Schema 文档:<xs:import>
和 <xs:include>
。 xs:include 旨在在包含文档的名称空间与被引用的名称空间相同时使用,因此它不是您要查找的内容。当您需要引用被引用架构中的所有(或子集)元素并且它们位于不同的目标命名空间中时,xs:import 更适合您的情况。这里有一个关于差异的问题:What's the difference between xsd:include and xsd:import?。
不管怎样,回到这个具体的问题。你可能想要的是这样的:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns="http://example.com/namespace/for/ElementB"
targetNamespace="http://example.com/namespace/for/ElementB"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns:ea="http://example.com/namespace/for/ElementA">
<xs:import namespace="http://example.com/namespace/for/ElementA" schemaLocation="A.xsd" />
<xs:element name="ElementB">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="xs:string" />
<xs:element name="bar" type="xs:string" />
<!-- This introduces a element named ElementA that uses the ComplexType ea:ElementA defined in A.xsd -->
<xs:element name="ElementA" type="ea:ElementA" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
尽管您需要 A.xsd 为 ElementA 创建一个复杂类型,您可以在 B.xsd 中使用,如图所示。
这篇文章有一些很好的信息/示例,并讨论了一些不同的可组合性策略:http://www.xfront.com/ZeroOneOrManyNamespaces.html
【讨论】:
谢谢,看起来不错,我试试。不过有一个问题,ea:
命名空间前缀从何而来?或者是name
类型定义在A.xsd
中得到?
只需在代码窗口上向右滚动 - 它被引用为 xs:schema 元素中的最后一个属性:xmlns:ea="http://example.com/namespace/for/ElementA"
。你可以给它任何你想要的前缀,就像你可以给默认的目标命名空间一样(尽管每个人总是按照约定选择xs
或xsd
)。
哦,懒得滚动那么远,错过了,对不起xD也感谢您的帮助,我会尽快尝试并发布我的结果:)
@somedave :我也有类似的情况。但我的问题是 elementB 没有命名空间声明,而只有 elemenA 有命名空间声明。那么我应该如何只包括那个。此外,元素 A 没有 xsd。唯一需要检查的是元素 A 是否包含该命名空间声明。
如果 ElementA 有一个名为 Bazz 的子元素,则验证库会在该 “元素 'Bazz':该元素不是预期的” 上给出错误。这可能是什么原因?【参考方案2】:
您可以使用<xsd:import>
标签来导入具有另一个命名空间的架构。
【讨论】:
你能给我一个例子来说明如何在上面的例子中使用它吗?您的链接并没有真正解释这一点..以上是关于带有来自其他命名空间的元素的 XSD的主要内容,如果未能解决你的问题,请参考以下文章
XML XSD 错误:org.xml.sax.SAXParseException:s4s-elt-schema-ns:元素“配置”的命名空间必须来自模式命名空间