如何使用出现约束为 XML 节点的无序列表创建模式 [英] How to create a schema for an unordered list of XML nodes, with occurrence constraints

查看:10
本文介绍了如何使用出现约束为 XML 节点的无序列表创建模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于这样的 XML 布局,我正在尝试创建一个 XSD 架构来验证它.

Given an XML layout like this, I'm trying to create a XSD schema to validate it.

<RootNode>
  <ChildA />
  <ChildC />
  <ChildB />
  <ChildB />
  <ChildA />
</RootNode>

要求如下:

  • ChildA、ChildB 和 ChildC 可以以任何顺序出现.(<xs:sequence> 不合适)
  • ChildA 是必填项,但可能会出现多次.
  • ChildB 是可选的,可能会出现多次.
  • ChildC 是可选的,可能只出现一次.
  • ChildA, ChildB and ChildC may occur in any order. (<xs:sequence> unsuitable)
  • ChildA is mandatory but may occur multiple times.
  • ChildB is optional and may occur multiple times.
  • ChildC is optional and may occur once only.

我通常用来创建无序列节点列表的技术是使用 <xs:choice maxOccurs="unbounded"> 与列表中的每个可能节点,但是,我无法在 ChildA 上创建 minOccurs="1" 约束和在 ChildC 上创建 maxOccurs="1" 约束.(选择的出现次数优先于此处元素的出现次数).

The technique I usually use to create an unordered list of nodes is to use a <xs:choice maxOccurs="unbounded"> with each possible node in the list, however, I am unable to create the minOccurs="1" constraint on ChildA and the maxOccurs="1" contraint on ChildC. (The # of occurances of the choice takes precedence over those of the elements here).

<xs:element name="RootNode">
  <xs:complexType>
    <xs:choice minOccurs="1" maxOccurs="unbounded">
      <xs:element name="ChildA" minOccurs="1"/>
      <xs:element name="ChildB" />
      <xs:element name="ChildC" maxOccurs="1"/>
    </xs:choice>
  </xs:complexType>
</xs:element>

推荐答案

更新:在 XSD 1.1m 中,对 all-groups 的一些限制已被解除.查看答案这里这里.

Update: In XSD 1.1m some of the constraints on all-groups have been lifted. See the answers here and here.

不是一个简单的,但似乎可行.这里的困难部分是模式定义必须是确定性的.我使用的方法是通过绘制问题的有限状态自动机来可视化问题,然后编写对应于该自动机的正则表达式.它一点也不像听起来那么复杂.不过,使用其他一些验证系统可能会提供更简单的答案.

Not a simple one but seems doable. Difficult part here is that Schema definitions must be deterministic. Approach I used was to visualize the problem by drawing a finite state automata of it and then to write a regular expression that corresponded that automata. It is not at all as complicated as it might sound. Still, using some other validation system would have likely provided simpler answer.

我已经做了一些测试,但是很容易漏掉一些特殊情况.如果您发现错误,请发表评论.

I have done some testing but missing out some special cases is easy. Please comment if you spot an error.

...这里是代码:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >

    <!-- Schema for elements ChildA, ChildB and ChildC
        The requirements are as follows:
            * ChildA, ChildB and ChildC may occur in any order.
            * ChildA is mandatory but may occur multiple times.
            * ChildB is optional and may occur multiple times.
            * ChildC is optional and may occur once only.
    -->

    <xsd:element name="root">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="ABC-container" type="ABC" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:complexType name="ABC">
        <xsd:sequence>
            <xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:choice>
                <xsd:sequence maxOccurs="1">
                    <xsd:element name="ChildC" type="xsd:string"/>
                    <xsd:element name="ChildB" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
                    <xsd:element name="ChildA" type="xsd:string"/>
                    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                        <xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
                        <xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
                    </xsd:sequence>
                </xsd:sequence>
                <xsd:sequence maxOccurs="1">
                    <xsd:element name="ChildA" type="xsd:string" minOccurs="1"/>
                    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                        <xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
                        <xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
                    </xsd:sequence>
                    <xsd:sequence minOccurs="0" maxOccurs="1">
                        <xsd:element name="ChildC" type="xsd:string"/>
                        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                            <xsd:element name="ChildA" type="xsd:string" minOccurs="0"/>
                            <xsd:element name="ChildB" type="xsd:string" minOccurs="0"/>
                        </xsd:sequence>
                    </xsd:sequence>
                </xsd:sequence>
            </xsd:choice>
        </xsd:sequence>
    </xsd:complexType>

</xsd:schema>

这篇关于如何使用出现约束为 XML 节点的无序列表创建模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆