带有来自其他命名空间的元素的 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 文档:&lt;xs:import&gt;&lt;xs:include&gt;。 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"。你可以给它任何你想要的前缀,就像你可以给默认的目标命名空间一样(尽管每个人总是按照约定选择xsxsd)。 哦,懒得滚动那么远,错过了,对不起xD也感谢您的帮助,我会尽快尝试并发布我的结果:) @somedave :我也有类似的情况。但我的问题是 elementB 没有命名空间声明,而只有 elemenA 有命名空间声明。那么我应该如何只包括那个。此外,元素 A 没有 xsd。唯一需要检查的是元素 A 是否包含该命名空间声明。 如果 ElementA 有一个名为 Bazz 的子元素,则验证库会在该 “元素 'Bazz':该元素不是预期的” 上给出错误。这可能是什么原因?【参考方案2】:

您可以使用&lt;xsd:import&gt; 标签来导入具有另一个命名空间的架构。

【讨论】:

你能给我一个例子来说明如何在上面的例子中使用它吗?您的链接并没有真正解释这一点..

以上是关于带有来自其他命名空间的元素的 XSD的主要内容,如果未能解决你的问题,请参考以下文章

使用 xslt 引用具有不同命名空间的元素

XML XSD 错误:org.xml.sax.SAXParseException:s4s-elt-schema-ns:元素“配置”的命名空间必须来自模式命名空间

xsd:any 元素的命名空间前缀并使用 XSLT 添加命名空间前缀

xsd2code 元素命名空间前缀问题

XML的Schema约束

『XML』XML/XSD命名空间解析