我想使用XSD 1.1并创建一个允许基于属性值的替代方案的模式。我已经通过其他一些帖子找到了如何做到这一点。但是,我有一个用例,我似乎无法找到任何地方,也没有答案。
我想要一个或多个名为PARAM的元素。这些元素中的每一个都具有“key”属性,并且基于此属性的值,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" />
这个错误:
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处理的情况下运行它。