"Unique Particle Attribution" 违规

"Unique Particle Attribution" violation

我编写了以下(简化的)架构来验证我收到的一些 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

    <xs:element name="Param">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="RadioAddr" type="xs:string" />
                <xs:element name="DataToRead" type="xs:integer" minOccurs="0" maxOccurs="1" />
                <xs:choice minOccurs="0" maxOccurs="1">
                    <xs:group ref="Group1" />
                    <xs:group ref="Group2" />
                    <xs:group ref="Group3" />
                </xs:choice>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:group name="Group1">
        <xs:sequence>
            <xs:element ref="Password" />
            <xs:element name="RadioActivated" type="xs:integer" minOccurs="0" maxOccurs="1" />
            <xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
            <xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
        </xs:sequence>
    </xs:group>

    <xs:group name="Group2">
        <xs:sequence>
            <xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
            <xs:element ref="Password" />
            <xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
        </xs:sequence>
    </xs:group>

    <xs:group name="Group3">
        <xs:sequence>
            <xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
            <!-- No password here -->
            <xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
        </xs:sequence>
    </xs:group>

    <xs:element name="Password" type="xs:string" />
    <xs:element name="IdNumber" type="xs:integer" />
    <xs:element name="AdjustClock" type="xs:integer" />

</xs:schema>

验证此架构时,我收到以下错误消息:

Not valid. Error - Line 5, 25: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 25; cos-nonambig: Password and Password (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.

我完全理解其中的歧义,但我找不到使我的架构有效的解决方案。

一个可能的解决方案是做类似

的事情
<xs:element name="Param>
    <xs:complexType>
        <xs:choice maxOccurs="unbounded">
            <!-- put all the possible elements here -->
        </xs:choice>
    </xs:complexType>
</xs:element>

但是这个解决方案的问题是我失去了一个对我进一步有用的抽象级别(组)(我使用这个模式通过 JAXB 生成 Java 类)。

那么,有没有办法使用 <xs:group> 让我的架构有效,或者我是否必须展平我的架构(就像我上面提到的解决方案)?

更新

以下是 XSD 应允许的示例:

允许的最小值:

<Param>
    <RadioAddr>1</RadioAddr>
</Param>

也是合法的:

<Param>
    <RadioAddr>1</RadioAddr>
    <Password>1234</Password>
</Param>

<Param>
    <RadioAddr>1</RadioAddr>
    <Password>1234</Password>
    <RadioActivated>1</RadioActivated>
    <IdNumber>12345678</IdNumber>
</Param>

<Param>
    <RadioAddr>1</RadioAddr>
    <IdNumber>12345678</IdNumber>
    <Password>1234</Password>
</Param>

要克服唯一粒子属性违规,您必须允许解析器明确知道它在语法中的位置,而不必向前看不止一个元素。

出现当前错误是因为在遇到Password元素时无法知道解析器是在Group1还是Group2,因为IdNumber是可选的。您可以改为强制使用 IdNumber,但这会在 Group2Group3 之间产生歧义,而不是 IdNumber。然后您可能会尝试使用排序来区分 xs:choice 组,但随后您会发现元素的可选性使您的努力付诸东流。您可能会删除可选性,如果组之间的不同排序是可以接受的,那么您可能会得到答案。

但是,这将是一个相当奇怪的语法。在这一点上,你可能会像你提到的那样更好地展平,而不是使用无限制的 xs:choice,这将允许任意和无限制地重复其元素,你可以通过一个简单的 xs:sequence 的元素改为:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

  <xs:element name="Param">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="RadioAddr" type="xs:string" />
        <xs:element name="DataToRead" type="xs:integer" minOccurs="0" maxOccurs="1" />
        <xs:element name="RadioActivated" type="xs:integer" minOccurs="0" maxOccurs="1" />
        <xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
        <xs:element ref="Password" minOccurs="0"/>
        <xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="Password" type="xs:string" />
  <xs:element name="IdNumber" type="xs:integer" />
  <xs:element name="AdjustClock" type="xs:integer" />

</xs:schema>