使用 XSD 验证多个根

时间:2021-06-24 18:10:39

标签: xml xsd xsd-validation

我正在处理这个项目,我们只允许使用一个 XSD 文件来验证多个 XML 文件。

我有这个问题,我似乎无法弄清楚,也找不到之前问过的类似问题,如果这是一个重复的问题,我深表歉意。

假设我有一个名为 currencies.xml 的 XML 文档,其中包含以下 XML:

<index>
    <currency>USD</currency>
    <currency>EURO</currency>
</index>

必须至少包含 1 个 <currency\> 元素,但可以根据需要包含多个元素。 现在,假设我有多个与 currencies.xml 中的货币值同名的其他 XML 文件,但为了简单起见,让我们仅采用包含以下内容的美元货币文件 USD.xml

<index>currency="USD">
    <country short="USA">United States of America</country>
</index>    

这次允许有 0 个 <country\> 元素,也可以根据需要增加。

所以在我的验证 XSD 文件中,我有以下内容:

<xs:complexType name="root">
    <xs:choice>
        <xs:element name="currency" type="WithoutAttrib"/>
        <xs:element name="country" type="WithAttrib"/>
    </xs:choice>
    <xs:attribute name="currency" type="rootAttribute" />
</xs:complexType>

<xs:complexType name="WithAttrib">
    <xs:complexContent>
        <xs:extension base="root">
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
                <xs:element name="country" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="stringElement">
                                <xs:attribute name="short" use="required"/>
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="WithoutAttrib">
    <xs:complexContent>
        <xs:extension base="root">
            <xs:sequence minOccurs="1" maxOccurs="unbounded">
                <xs:element name="currency">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="30"></xs:maxLength>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:element name="index" type="root"/>

stringElement 的定义如下:

<xs:simpleType name="stringElement">
    <xs:restriction base="xs:string"/>
</xs:simpleType>

到目前为止,这是我能想出的最佳解决方案,但它不能按我的需要工作,有人可以通过提供指向我可以使用的类似问题的链接或给我的链接来帮助我关于如何使这项工作发挥作用的一些建议。

我也不完全确定是否应该在根中声明该属性,任何有关它的建议也将不胜感激。

如果您需要有关特定内容的更多信息,请给我留言,我会进行编辑。提前致谢!

1 个答案:

答案 0 :(得分:0)

您在 XML 中没有任何内容可以区分您需要的架构规则,因此您的 XSD 必须是 <index> 中所有有效属性和元素的超集。 XML 格式是固定的还是可以更改?

以下执行您想要的操作,但由于您在 index 元素中有属性,因此 choice 无法将该属性与 country 元素分组。

它不太理想。

enter image description here

  <?xml version="1.0" encoding="utf-8" ?>
  <!--Created with Liquid Studio 2021 (https://www.liquid-technologies.com)-->
  <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="index">
        <xs:complexType>
           <xs:choice>
              <xs:element name="currency" type="currencyType" maxOccurs="unbounded" />
              <xs:element name="country">
                 <xs:complexType>
                    <xs:simpleContent>
                       <xs:extension base="xs:string">
                          <xs:attribute name="short" type="currencyType" />
                       </xs:extension>
                    </xs:simpleContent>
                 </xs:complexType>
              </xs:element>
           </xs:choice>
           <xs:attribute name="currency" type="currencyType" />
        </xs:complexType>
     </xs:element>
     <xs:simpleType name="currencyType">
        <xs:restriction base="xs:string">
           <xs:enumeration value="USD" />
           <xs:enumeration value="GBP" />
           <xs:enumeration value="EUR" />
        </xs:restriction>
     </xs:simpleType>
  </xs:schema>