将xs:alternate与可能具有或不具有元素的扩展类型一起使用

时间:2019-03-29 15:10:23

标签: xml validation xsd

我想使用XSD 1.1并创建一个架构,该架构允许基于属性值的替代方案。我通过其他一些帖子发现了如何做到这一点。但是,我有一个用例,我似乎找不到任何地方,也找不到答案。

我希望有1个或多个名称为PARAM的元素。这些元素中的每一个都具有“键”属性,并且根据该属性的值,PARAM元素可能具有子元素,也可能没有子元素(可能仅具有其他属性)。

但是,我收到一条错误消息,暗示可能无法实现,但找不到任何文档或要确认的内容。

这是我的XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="CONFIG">
        <xs:complexType>
            <xs:sequence>
                <!-- any number of PARAM elements, setting alternative types based on the key attribute value -->
                <xs:element name="PARAM" type="baseParamType" maxOccurs="unbounded">
                    <xs:alternative test="@key='printers'" type="printerParamType"/>
                    <xs:alternative test="@key!='printers'" type="nonPrinterParamType"/>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <!--
        Type Declarations
    -->

    <!-- base PARAM type -->
    <xs:complexType name="baseParamType">
        <xs:attribute name="key" use="required" type="paramKeyTypes"/>
    </xs:complexType>

    <!-- PARAM for printers -->
    <xs:complexType name="printerParamType">
        <xs:complexContent>
            <!-- extend the base PARAM type -->
            <xs:extension base="baseParamType">
                <!-- the printer PARAM can have a child FORMAT element -->
                <xs:sequence>
                    <xs:element name="FORMAT" maxOccurs="unbounded">
                        <xs:complexType>
                            <xs:attribute name="name" use="required" type="printerFormatType"/>
                            <xs:attribute name="printer" use="required" type="xs:string"/>
                        </xs:complexType>
                    </xs:element>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <!-- PARAM for anything but printers -->
    <xs:complexType name="nonPrinterParamType">
        <xs:complexContent>
            <xs:extension base="baseParamType">
                <xs:attribute name="value" use="required" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <!-- valid values for the key attribute of PARAM elements -->
    <xs:simpleType name="paramKeyTypes">
        <xs:restriction base="xs:string">
            <xs:enumeration value="printers"/>
            <xs:enumeration value="locale"/>
            <xs:enumeration value="debug_mode"/>
            <xs:enumeration value="num_threads"/>
            <xs:enumeration value="serial_printer"/>
            <xs:enumeration value="parallel_printer"/>
            <xs:enumeration value="NCRTwoLine"/>
            <xs:enumeration value="requires_line_AB"/>
            <xs:enumeration value="printer_type"/>
            <xs:enumeration value="epson_mode"/>
            <xs:enumeration value="sequence_file"/>
            <xs:enumeration value="disable_cashdrawer"/>
            <xs:enumeration value="tax_label"/>
            <xs:enumeration value="dynamic_gateway_config"/>
            <xs:enumeration value="gateway_settings"/>
            <xs:enumeration value="use_static_gateway_config"/>
        </xs:restriction>
    </xs:simpleType>

    <!-- valid values for printer names -->
    <xs:simpleType name="printerFormatType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="default" />
            <xs:enumeration value="receipt" />
            <xs:enumeration value="ticket" />
            <xs:enumeration value="season_pass" />
            <xs:enumeration value="forms" />
            <xs:enumeration value="demographics" />
            <xs:enumeration value="group" />
            <xs:enumeration value="report" />
            <xs:enumeration value="boca" />
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

这是正在验证的文件:

<?xml version="1.0"?>
<CONFIG xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="config.xsd">
    <PARAM key="printers">
        <FORMAT name="default" printer="Microsoft XPS Document Writer" />
        <FORMAT name="receipt" printer="Microsoft XPS Document Writer" />
        <FORMAT name="group" printer="Microsoft XPS Document Writer" />
        <FORMAT name="ticket" printer="Microsoft XPS Document Writer" />
        <FORMAT name="season_pass" printer="Microsoft XPS Document Writer" />
    </PARAM>

    <PARAM key="dynamic_gateway_config" value="http://test-shop.accesso.com/pos/getEnvironment.php" island="accesso90"/>
</CONFIG>

我得到的错误:

[Error] config.xsd:9:85: s4s-elt-must-match.1: The content of 'PARAM' must match (annotation?, (simpleType | complexType)?, (unique | key | keyref)*)). A problem was found starting at: alternative.
[Error] config.cfg:10:13: cvc-complex-type.2.1: Element 'PARAM' must have no character or element information item [children], because the type's content type is empty.
[Error] config.cfg:12:121: cvc-complex-type.3.2.2: Attribute 'value' is not allowed to appear in element 'PARAM'.
[Error] config.cfg:12:121: cvc-complex-type.3.2.2: Attribute 'island' is not allowed to appear in element 'PARAM'.
[Error] config.cfg:10:13: cvc-complex-type.2.1: Element 'PARAM' must have no character or element information item [children], because the type's content type is empty.
[Error] config.cfg:12:121: cvc-complex-type.3.2.2: Attribute 'value' is not allowed to appear in element 'PARAM'.
[Error] config.cfg:12:121: cvc-complex-type.3.2.2: Attribute 'island' is not allowed to appear in element 'PARAM'.

我最关心的是第一个错误,它指出PARAM必须没有字符或元素信息,因为类型的内容为空。我认为是因为我的'baseParamType'类型没有定义元素,键值为'printers'的PARAM不能包含任何子元素,但这是一个小词。 >

我想要拥有的是能够在同一XML中同时具备以下两项功能

<PARAM key="printers">
    <FORMAT name="someName" printer="Some printer name" />
</PARAM>

<PARAM key="anythingButPrinters" value="some value" />

1 个答案:

答案 0 :(得分:0)

此错误:

The content of 'PARAM' must match (annotation?, (simpleType | complexType)?,
 (unique | key | keyref)*)). A problem was found starting at: alternative.

很好地表明它抱怨的是模式而不是实例文档,尽管我总是感到奇怪,Xerces谈论的是“ PARAM”的内容,而不是“ xs:element的内容”。 / p>

这一切在Saxon-EE 9.9中都有效,因此它要么是Xerces中的错误,要么是您以某种方式启用了未启用XSD 1.1处理的功能。