唯一粒子错误,想允许多个子元素任意顺序

Unique particle error, want to allow multiple child elements in any order

我正在尝试验证项目中的一些现有 XML 文件。示例结构如下所示:

<resources>
    <file name="one" path="C:\test\one.txt" />
    <cache path="C:\test\cache\" />
    <file name="two" path="C:\test\two.txt" />
    <bundle name="myFolder">
        <file name="three" path="C:\test\three.txt" />
        <file name="four" path="C:\test\four.txt" />
    </bundle>
    <file name="one" path="C:\test\one.txt" />
    <bundle name="myFolder">
        <file name="three" path="C:\test\three.txt" />
        <file name="four" path="C:\test\four.txt" />
    </bundle>
    <file name="one" path="C:\test\one.txt" />
</resources>

换句话说,我想要的是一个具有根元素 resources 的结构,它有子元素

这是我现在的XSD(取自this answer):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="cache">
        <xs:attribute name="path" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="file">
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="path" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="bundle">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="file" type="file" maxOccurs="unbounded" />
        </xs:choice>
        <xs:attribute name="type" />
        <xs:attribute name="name" />
    </xs:complexType>

    <xs:group name="unboundednoncache">
        <xs:choice>
            <xs:element name="file" type="file" />
            <xs:element name="bundle" type="bundle" />
        </xs:choice>
    </xs:group>

    <xs:element name="resources">
        <xs:complexType>
            <xs:sequence>
                <!-- Validates if this next line is removed,
                and the cache element is moved to first -->
                <xs:group ref="unboundednoncache" minOccurs="0" maxOccurs="unbounded" />
                <xs:element name="cache" type="cache" minOccurs="0" maxOccurs="1" />
                <xs:group ref="unboundednoncache" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

这给了我错误:

Cos-nonambig: File And File (or Elements From Their Substitution Group) Violate "Unique Particle Attribution". During Validation Against This Schema, Ambiguity Would Be Created For Those Two Particles.

如果我删除 XSD 中的第一个 <xs:group> 并将 cache 元素移动为第一个子元素,我可以获得第一个 XSD 进行验证XML,但我希望缓存元素在任何地方都有效。

(在此版本之前我使用的是:

<xs:choice maxOccurs="unbounded">
    <xs:element name="cache" type="cache" minOccurs="0" maxOccurs="1" />
    <xs:element name="file" type="file" minOccurs="0" maxOccurs="unbounded" />
    <xs:element name="bundle" type="bundle" minOccurs="0" maxOccurs="unbounded" />
</xs:choice>

..但这允许多个缓存元素,我也不想要。)

为什么我的 XSD 违反了 "unique particle attribution",我该如何解决?

在您的架构文档中,您已将 resources 的内容模型编写为

的等效内容模型
((file | bundle)*, cache?, (file | bundle)*)

这在语义上是正确的,但是初始 file 元素可以匹配内容模型中 file 的第一次出现或第二次出现。出于最好隐瞒的原因,XSD 不允许这样做。

因此您需要一个确定性的等效内容模型。并非所有 non-deterministic 内容模型都具有确定性等价物,但您的有:

((file | bundle)*, (cache, (file | bundle)*)?)

或者,在 XSD 语法中(重用您对 unboundednoncache 的定义):

<xs:group name="cache-plus-noncache">
  <xs:sequence>
    <xs:element name="cache" type="cache" 
                minOccurs="1" maxOccurs="1" />
    <xs:group ref="unboundednoncache" 
              minOccurs="0" maxOccurs="unbounded" />
  </xs:sequence>
</xs:group>

<xs:element name="resources">
  <xs:complexType>
    <xs:sequence>
      <xs:group ref="unboundednoncache" 
                minOccurs="0" maxOccurs="unbounded" />
      <xs:group ref="cache-plus-noncache" 
                minOccurs="0" maxOccurs="1" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

拥有一个读取内容模型的工具可能会很方便,它可以检测到对确定性(aka 'unique particle attribution')规则的违反,并提出一个确定性等价物或打破内容模型没有的坏消息确定性等价物。这个理论已经被 Anne Brüggemann-Klein 完美地阐述出来了。但到目前为止,我还不知道有这样的工具,而且我定期写一个工具的决心至今没有结果。