我认为我需要做的是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
中的字段orig:fieldA
限制在targetNamespace="http://myns.myns".当然,如果像我在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
仅具有整数值。但现在,你说它可以接受任何东西。这肯定会导致错误,而你收到的信息(尽管确实有些胡言乱语):
类型的粒子不是基粒子的有效限制
似乎是在说这件事。