Использование xs: альтернатива расширенным типам, которые могут иметь или не иметь элементы - PullRequest
0 голосов
/ 29 марта 2019

Я хотел бы использовать 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' не имеет элементов, определенных, то у PARAM со значением ключа 'printers' не может быть никаких дочерних элементов, но это немного загадочно.

Я хотел бы иметь возможность иметь оба следующих элемента в одном и том же XML

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

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

1 Ответ

0 голосов
/ 29 марта 2019

Эта ошибка:

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

является довольно хорошим показателем того, что он жалуется на схему, а не на экземпляр документа, хотя мне всегда кажется странным, что Xerces говорит о «контенте PARAM», а не о «контенте xs: element».

Все это считается действительным в Saxon-EE 9.9, так что это либо ошибка в Xerces, либо, скорее всего, вы каким-то образом запускаете ее так, что обработка XSD 1.1 не включена.

...