XSD:允许任何顺序的任何未知元素

时间:2015-09-23 14:12:18

标签: xml xsd

我需要编写一个XSD架构。在此模式中,某些元素是已知且必需的,其他元素是未知的和可选的:

<father>
    <childMandatory1 />
    <childMandatory2 />
    <childOptionnal1 />
</father>

或:(更改强制性儿童订单)

<father>
    <childMandatory2 />
    <childMandatory1 />
</father>

我知道强制性的孩子(但不是他们的命令)。但我不知道是否会有任何可选的孩子(如果是的话,他们的名字)。

我试过&#34; xs:all&#34;,但&#34; xs:all&#34;不允许&#34;任何&#34; :

<xs:element name="father">
        <xs:complexType>
            <xs:all>
                <xs:element ref="childMandatory1" />
                <xs:element ref="childMandatory2" />
                <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> 
        <!-- error here ! -->
                </xs:all>
            </xs:complexType>
    </xs:element>

我尝试了序列,但我应该知道元素的顺序。 (而且我不会)

我尝试了选择,但选择不能与任何和一些强制性元素一起使用。 (我想确保强制要素存在)

1 个答案:

答案 0 :(得分:0)

根据您的要求,您已达到“唯一粒子归因”规则,该规则非常重要it has its own Wikipedia page

问题在于将任何订单任何元素结合起来。处理器无法确定地确定某个元素属于哪个声明。 childMandatory1是属于xs:any还是属于元素声明?

只要您使用xs:any,就可以轻松遇到此问题。这就是为什么允许序列与xs:any组合的原因,但前提是序列中的项是强制性的并按顺序排列,否则再也不知道哪个元素属于什么声明。

如果您创建此类XSD的原因是验证输入是否存在某些元素,您可以切换到XSD 1.1,您可以使用xs:assert解决此问题,或者您可以使用其他工具,例如RelaxNg或Schematron,它们是替代的标准化XML模式语言。

如果你想用这个创建一个对象模型,你可能会运气不好,因为即使你设法这样做,(de)序列化器也无法告诉彼此的声明。

这是XSD 1.1中的一个例子:

<xs:complexType name="BookType">
    <xs:all>
        <xs:any maxOccurs="unbounded" namespace="##any" />
    </xs:all>
    <xs:assert test="self::author | self::title | self:isbn" xpathDefaultNamespace="urn:test" />
</xs:complexType>

可以在XFront上找到关于writing extensible XSD Schema's using Variable Content Containers的好文章。虽然陈旧,但今天仍然非常适用。还有article on the use of xs:any