xml – 限制其他命名空间中的类型元素

我认为我需要做的事情不可能用XSD 1.0,但无论如何我会问……

我在文件中有一个complexType,比如a.xsd.原则上,我无法触摸此文件.特别是,我无法更改其targetNamespace.一个例子是:

<xs:schema targetNamespace="http://myns.original" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:orig="http://myns.original">

  <xs:element name="config" type="orig:ConfigType"/>

  <xs:complexType name="ConfigType">
    <xs:sequence>
      <xs:element name="fieldA" type="xs:integer" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

我有第二个文件b.xsd,其中我扩展了a.xsd中定义的类型,并使用substitutionGroup重新定义先前在a.xsd中定义的元素.现在一切都很好,以下示例似乎没问题:

<xs:schema targetNamespace="http://myns.myns" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:myns="http://myns.myns" xmlns:orig="http://myns.original">

  <xs:import namespace="http://myns.original" schemaLocation="a.xsd"/>

  <xs:complexType name="ConfigType">
    <xs:complexContent>
      <xs:extension base="orig:ConfigType">
        <xs:sequence>
          <xs:element name="fieldB" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:element name="config" type="myns:ConfigType" substitutionGroup="orig:config"/>

</xs:schema>

问题即将来临:原始complexType中的一个字段是可选的(minOccurs = 0).现在,我需要重新定义此类型,以便该字段是必需的(minOccurs = 1).我猜这可以通过xsd:redefine实现,所以我尝试了以下方法:

<xs:schema targetNamespace="http://myns.myns" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:myns="http://myns.myns">

  <xs:redefine schemaLocation="b.xsd">

    <xs:complexType name="ConfigType">
      <xs:complexContent>
        <xs:restriction base="myns:ConfigType">
          <xs:sequence>
            <xs:element name="fieldA" minOccurs="1"/>
          </xs:sequence>
        </xs:restriction>
      </xs:complexContent>
    </xs:complexType>

  </xs:redefine>

</xs:schema>

但我收到以下消息:

 There is not a complete functional mapping between the particles.
 Error for type 'ConfigType'.  The particle of the type is not a valid restriction of the particle of the base.

老实说,我不太了解这些消息,但经过一些调查后,似乎实际问题是重新定义的字段必须属于与重新定义完全相同的命名空间.在我的例子中,我尝试在名称空间http://myns.original中,在targetNamespace =“http://myns.myns”的文件中限制字段orig:fieldA.当然,如果像我在b.xsd中那样继续扩展c.xsd中的类型,那就没有问题,因为我不会尝试从不同的命名空间修改任何内容.

有人知道这是否可以实现?一种解决方案是使用正确的targetNamespace复制将在不同文件a_2.xsd中修改的定义.但对于复杂系统而言,这是一个非常不受欢迎且难以维护的解决方案.

最佳答案 到目前为止我唯一看到的问题是在架构a.xsd中你定义了:

<xs:element name="fieldA" type="xs:integer" minOccurs="0"/>

而在最后一个模式(重新定义)中,您有:

<xs:element name="fieldA" minOccurs="1"/>

最后一个声明的实际含义是你隐式为fieldA指定xs:anyType:

<xs:element name="fieldA" type="xs:anyType" minOccurs="1"/>

请记住,当你通过限制派生出一种新类型时(实际上就是你
在重新定义中,您必须完全重新定义元素内容模型.
但是,新内容模型必须完全符合旧内容模型.

在你的上一个模式中并非如此,因为之前
根据a.xsd,元素fieldA只允许有整数值.
但现在,你说它可能接受任何东西.
这肯定会导致错误,以及你收到的消息(虽然确实相当喋喋不休):

该类型的颗粒不是对碱的颗粒的有效限制.

好像在说这个.

点赞