【问题标题】:Using an element from another schema as a nested element使用来自另一个模式的元素作为嵌套元素
【发布时间】:2015-07-24 16:37:05
【问题描述】:

我需要编写一个模式(比如 A.xsd),它使用为不同项目编写的第二个模式(比如 B.xsd)中的元素。预先存在的模式(即 B.xsd)定义了几个顶级元素。例如:

来自 B.xsd 的片段:

<xs:element name="macAddress">
    <xs:complexType>
    ....
</xs:complexType>
</xs:element>

但是,当我在 A.xsd 中使用 B.xsd 中的这些元素时,它们需要是其他一些元素的内部嵌套元素,而不是像在 B.xsd 中那样的顶级元素。因此,macAddress 和其他元素的 A.xsd 命名空间的简单“导入”似乎对我不起作用,因为导入导致这些元素也成为 A.xsd 的顶级元素。

然后我尝试对 B.xsd 中的顶级元素使用“abstract=true”属性,如下所示:

<xs:element name="macAddress" abstract="true">
<xs:complexType>
    ....
</xs:complexType>
</xs:element>

然后写A.xsd如下:

<xs:import namespace="urn:xyz:BNamespace"
          schemaLocation="file:///C:\Users\a\Documents\B.xsd"/>
<xs:element name="root">
<xs:complexType>
        <xs:sequence>
        <xs:element ref="BPrefix:macAddress"/> <!-- BPrefix is defined -->
    </xs:sequence>
   </xs:complexType>
</xs:element>

但是,此架构随后会在验证期间生成以下错误: “QName {urn:xyz:BNamespace}macAddress 无法解析为 (n) 元素声明。”

我无法理解此错误的含义。请注意,当元素在 A.xsd 本身中定义时,不会发生此错误。但是,网络上的一些参考资料表明“ref”属性允许使用外部命名空间前缀。

有人可以指出我的 A.xsd 架构中的错误是什么吗?或者建议以某种方式实现我的原始要求,这基本上是编写一个使用来自另一个模式的元素定义作为嵌套内部元素的模式?

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

    是的,一个元素必须是全局定义的,以便在本地定义中@ref它,然后这将允许该全局定义的元素作为文档中可能的替代根元素出现。无论您的 XSD 是针对一个文件还是多个文件定义都是如此。

    要拥有纯本地元素,请改为定义全局类型,并使用@type 来引用共享的全局类型,而不是使用@ref 来引用全局定义的元素。

    【讨论】:

    • 感谢@kjhughes 的回复。我确实考虑将 B.xsd 中的元素定义更改为全局类型定义而不是元素定义。但是,其中一些元素定义需要有 子元素。似乎 不能在其中包含关键信息,理想情况下,我希望所有描述这些元素/类型的标签都只在 B.xsd 中,并且只在 A.xsd 中按名称/类型引用它们。
    【解决方案2】:

    假设您在B.xsd 中声明了macAddress 元素,如下所示::

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:xyz:BNamespace"> 
    
        <xs:element name="macAddress">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="X"/>
                </xs:sequence>
         </xs:complexType>
        </xs:element>
    </xs:schema>
    

    您可以在另一个架构 (A.xsd) 中使用此元素,如下所示:

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:BPrefix="urn:xyz:BNamespace"> 
    
        <xs:import namespace="urn:xyz:BNamespace"
            schemaLocation="file:///C:\Users\a\Documents\B.xsd"/>
        <xs:element name="root">
            <xs:complexType>
                <xs:sequence>
                    <xs:element ref="BPrefix:macAddress"/> <!-- BPrefix is defined -->
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    

    【讨论】:

    • 如果没有 B.xsd 中 'macAddress' 元素定义的 'abstract=true' 属性,我的架构将开始允许 macAddress 元素成为顶级元素以及嵌套元素,我不这样做不想让。因此我需要使用抽象属性。
    猜你喜欢
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多