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

XSD: Allow any unknown element in any order

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

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

或:(更改强制性 children 顺序)

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

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

我尝试使用 "xs:all",但 "xs:all" 不允许 "any" :

<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>

我试过顺序,但我应该知道元素的顺序。 (我没有)

我试过使用 choice,但 choice 不能用于任何和某些强制性元素。 (我想确保存在强制性元素)

根据您的要求,您已经达到了独特的粒子属性规则,这个规则非常重要 it has its own Wikipedia page

问题在于将任意顺序任意位置的任意元素组合在一起。处理器无法确定性地确定某个元素属于哪个声明。 childMandatory1是属于xs:any还是属于元素声明?

只要你使用xs:any你就可以轻松运行进入这个问题。这就是为什么允许使用 xs:any 组合序列的原因,但前提是序列中的项目是强制性的且按顺序排列的,否则也不知道哪个元素属于哪个声明。

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

如果你想从中创建一个对象模型,你可能 运行 运气不好,因为即使你设法做到了,(反)序列化器也无法分辨来自的声明彼此。

这是 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>

一篇关于 writing extensible XSD Schema's using Variable Content Containers can be found on XFront. While old, it still very much applies today. There's also an article on the use of xs:any 的好文章,很有帮助。