XML 模式的问题给出错误 #3070 内容模型不是确定性的

Problem with XML Schema giving Error #3070 The content model is not determinist

我有一个框架可以解析 XML 的配置。我已经删除了旧的 1.0 支持,现在正在尝试解析“验证器”配置。 validators.xsd 的内容与框架的其他部分相同(除了关键字验证器),没有任何问题。我只听说过内容模型不是确定性的,因此我发现很难解决问题。如果你能给我指出正确的方向以获得更好的错误或“健全性检查”,那就太好了。

这里是 XSD 配置以及正在使用的匹配 xml 符号。我不确定在这里放什么,但为了清楚起见,我将提供所有引用的内容。

validators.xsd

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:types="http://framework.youds.com/xml/config/global/types"
    xmlns:validators="http://framework.youds.com/xml/config/parts/validators"
    targetNamespace="http://framework.youds.com/xml/config/global/envelope"
    elementFormDefault="qualified"
    version="$Id$">

    <xs:import namespace="http://framework.youds.com/xml/config/global/types"
               schemaLocation="_types.xsd" />
    <xs:import namespace="http://framework.youds.com/xml/config/parts/validators"
               schemaLocation="parts/validators.xsd" />

    <xs:redefine schemaLocation="_envelope.xsd">

        <xs:complexType name="configuration">
            <xs:complexContent>
                <xs:extension base="configurations">
                    <xs:group ref="validators:configuration" />
                    <xs:attributeGroup ref="types:contexts" />
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>

    </xs:redefine>

</xs:schema>

parts/validators.xsd

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:envelope="http://framework.youds.com/xml/config/global/envelope"
    xmlns:types="http://framework.youds.com/xml/config/global/types"
    xmlns="http://framework.youds.com/xml/config/parts/validators"
    targetNamespace="http://framework.youds.com/xml/config/parts/validators"
    elementFormDefault="qualified"
    version="$Id$">

    <xs:import namespace="http://framework.youds.com/xml/config/global/types"
               schemaLocation="../_types.xsd" />
    <xs:import namespace="http://framework.youds.com/xml/config/global/envelope"
               schemaLocation="../_envelope.xsd" />

    <xs:simpleType name="severity">
        <xs:restriction base="xs:string">
            <xs:enumeration value="info" />
            <xs:enumeration value="silent" />
            <xs:enumeration value="none" />
            <xs:enumeration value="notice" />
            <xs:enumeration value="error" />
            <xs:enumeration value="critical" />
        </xs:restriction>
    </xs:simpleType>

    <!-- Arguments -->
    <xs:complexType name="argument">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="name" type="types:non_empty_string" use="optional" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="arguments">
        <xs:sequence>
            <xs:element name="argument" type="argument" minOccurs="0"
                        maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="base" type="xs:string" use="optional" />
    </xs:complexType>

    <xs:group name="arguments">
        <xs:choice>
            <xs:element name="arguments" type="arguments"
                        minOccurs="0" />
            <xs:element name="argument" type="argument"
                        minOccurs="0" maxOccurs="unbounded" />
        </xs:choice>
    </xs:group>

    <!-- Errors -->
    <xs:complexType name="error">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="for" type="types:non_empty_string" use="optional"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="errors">
        <xs:sequence>
            <xs:element name="error" type="error"
                        maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:group name="errors">
        <xs:choice>
            <xs:element name="errors" type="errors"
                        minOccurs="0" />
            <xs:element name="error" type="error"
                        minOccurs="0" maxOccurs="unbounded" />
        </xs:choice>
    </xs:group>

    <xs:complexType name="validator">
        <xs:sequence maxOccurs="unbounded">
            <xs:group ref="envelope:parameters" />
            <xs:group ref="arguments"
                      minOccurs="0"/>
            <xs:group ref="errors"
                      minOccurs="0"/>
            <xs:group ref="validators"
                      minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="class" type="types:php_class" />
        <xs:attribute name="depends" type="xs:string" />
        <xs:attribute name="export" type="xs:string" />
        <xs:attribute name="method" type="types:php_label_list" />
        <xs:attribute name="provides" type="xs:string" />
        <xs:attribute name="required" type="types:boolean" />
        <xs:attribute name="severity" type="severity" />
        <xs:attribute name="source" type="types:php_label" />
        <xs:attribute name="translation_domain" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="validators">
        <xs:sequence>
            <xs:element name="validator" type="validator"
                        minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="method" type="types:php_label_list" />
        <xs:attribute name="severity" type="severity" />
        <xs:attribute name="translation_domain" type="xs:string" />
    </xs:complexType>

    <xs:group name="validators">
        <xs:choice>
            <xs:element name="validators" type="validators"
                        minOccurs="0" />
            <xs:element name="validator" type="validator"
                        minOccurs="0" maxOccurs="unbounded" />
        </xs:choice>
    </xs:group>
    
    <xs:group name="configuration">
        <xs:sequence>
            <xs:sequence minOccurs="0" maxOccurs="unbounded" >
                <xs:group ref="validators"
                        minOccurs="0" maxOccurs="unbounded" />
                <xs:group ref="validators"
                        minOccurs="0" />
            </xs:sequence>
        </xs:sequence>
    </xs:group>

</xs:schema>

_types.xsd

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:types="http://framework.youds.com/xml/config/global/types"
    targetNamespace="http://framework.youds.com/xml/config/global/types"
    version="$Id$">

    <xs:simpleType name="environment_list">
        <xs:list itemType="xs:string" />
    </xs:simpleType>

    <xs:attributeGroup name="environments">
        <xs:attribute name="environment" type="types:environment_list" use="optional" />
    </xs:attributeGroup>

    <xs:simpleType name="context_list">
        <xs:list itemType="xs:string" />
    </xs:simpleType>

    <xs:attributeGroup name="contexts">
        <xs:attribute name="context" type="types:context_list" use="optional" />
    </xs:attributeGroup>

    <xs:simpleType name="non_empty_string">
        <xs:restriction base="xs:string">
            <xs:minLength value="1" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="php_class">
        <xs:restriction base="xs:string">
            <!--
                See Ticket #1132:
                We exclude all the useless stuff from the ASCII range: we allow _a-zA-Z0-9 (and _a-zA-Z for the first character) from Unicode u00-u7E plus all the rest defined in Unicode.
                Since we're supporting PHP 5.3+, we also allow backslashes from the second character on.
                The result is that the UTF-8 representation of such a string matches the regular expression ^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$ (applied to the raw bytes), which is the pattern for a valid PHP "LABEL".
                We start at &#9;, not &#0;, because #0-#8 are invalid XMLChars.
            -->
            <xs:pattern value="[^&#9;-&#64;\&#91;\&#92;\&#93;&#94;&#96;&#123;&#124;&#125;&#126;][^&#9;-&#47;&#58;-&#64;\&#91;\&#93;&#94;&#96;&#123;&#124;&#125;&#126;]*" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="php_class_list">
        <xs:list itemType="types:php_class" />
    </xs:simpleType>

    <xs:simpleType name="php_label">
        <xs:restriction base="types:php_class">
            <!-- no \ allowed -->
            <xs:pattern value="[^\]+" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="php_label_list">
        <xs:list itemType="types:php_label" />
    </xs:simpleType>

    <!-- for BC, should be removed after 1.1 or so -->
    <xs:simpleType name="identifier">
        <xs:restriction base="types:php_label" />
    </xs:simpleType>

    <!-- for BC, should be removed after 1.1 or so -->
    <xs:simpleType name="identifier_list">
        <xs:restriction base="types:identifier" />
    </xs:simpleType>

    <xs:simpleType name="boolean">
        <xs:restriction base="xs:string">
            <xs:pattern value="([tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[yY][eE][sS]|[nN][oO]|[oO][nN]|[oO][fF][fF])" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="matched">
        <xs:restriction base="types:boolean" />
    </xs:simpleType>

</xs:schema>

_envelope.xsd

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:envelope="http://framework.youds.com/xml/config/global/envelope"
    xmlns:types="http://framework.youds.com/xml/config/global/types"
    xmlns:annotations="http://framework.youds.com/xml/config/global/annotations"
    targetNamespace="http://framework.youds.com/xml/config/global/envelope"
    elementFormDefault="qualified"
    version="$Id$">

    <xs:import namespace="http://framework.youds.com/xml/config/global/types"
               schemaLocation="_types.xsd" />
    <xs:import namespace="http://framework.youds.com/xml/config/global/annotations"
               schemaLocation="_annotations.xsd" />
    <xs:import namespace="http://www.w3.org/XML/1998/namespace"
               schemaLocation="vendor/http/www.w3.org/XML/1998/namespace/2009-01.xsd" />

    <xs:attribute name="literalize" type="types:boolean" />

    <xs:complexType name="sandbox">
        <xs:sequence>
            <xs:any namespace="##any" processContents="lax"
                    minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="configuration">
        <xs:attributeGroup ref="annotations:match" />
        <xs:attributeGroup ref="types:environments" />
        <xs:anyAttribute namespace="##any" processContents="lax" />
    </xs:complexType>

    <xs:complexType name="configurations">
        <xs:sequence>
            <xs:any namespace="##other" processContents="lax"
                    minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="sandbox" type="envelope:sandbox"
                        minOccurs="0" maxOccurs="1" />
            <xs:element name="configuration" type="envelope:configuration"
                        minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="parent" type="xs:string" use="optional" />
        <xs:anyAttribute namespace="##any" processContents="lax" />
    </xs:complexType>

    <xs:complexType name="parameter" mixed="true">
        <xs:group ref="envelope:parameters" />
        <xs:attribute name="name" type="xs:string" use="optional" />
        <xs:attribute ref="xml:space" />
        <xs:attribute ref="envelope:literalize" />
    </xs:complexType>

    <xs:complexType name="parameters">
        <xs:sequence>
            <xs:element name="parameter" type="envelope:parameter"
                        minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:group name="parameters">
        <xs:choice>
            <xs:element name="parameters" type="envelope:parameters"
                        minOccurs="0" maxOccurs="1" />
            <xs:element name="parameter" type="envelope:parameter"
                        minOccurs="0" maxOccurs="unbounded" />
        </xs:choice>
    </xs:group>

    <xs:element name="configurations" type="envelope:configurations" />

</xs:schema>

test.xml

<ae:configurations
    xmlns="http://framework.youds.com/xml/config/parts/validators"
    xmlns:ae="http://framework.youds.com/xml/config/global/envelope"
    parent="%core.src_dir%/config/defaults/validators.xml"
>
    <configuration>
        
        <validators>
            <validator class="string">
                <arguments>
                    <argument>test</argument>
                </arguments>
                <errors>
                    <error>The test is not successful.</error>
                </errors>
                <ae:parameters>
                    <ae:parameter name="min">1</ae:parameter>
                </ae:parameters>
            </validator>
        </validators>
        
    </configuration>
</ae:configurations>

所以问题出在 /parts/validator.xsd 配置中,其中包含导致“non-determinist”错误的重复元素。作为参考,据我了解,此消息意味着您看到的是重复条目,或者更确切地说,是不清楚如何继续处理下一个元素的条目。因此,不是决定论者。

<xs:group ref="validators"
    minOccurs="0" maxOccurs="unbounded" />
<xs:group ref="validators"
    minOccurs="0" />

应该是:

<xs:group ref="validators"
    minOccurs="0" maxOccurs="unbounded" />