XSD 用于递归元素定义

XSD for recursive element definition

我遇到一个情况,我需要一个元素来嵌套自身或包含其他元素。

像这样应该是有效的:

<root>
  <rule condition="...">
    <rule condition="...">
      <setting>...</setting>
    </rule>
  </rule>
  <rule condition="...">
    <setting>...</setting>
  </rule>
</root>

但这应该有效:

<root>
  <rule condition="...">
    <rule condition="...">
      <setting>...</setting>
    </rule>
    <setting>...</setting>
    <setting>...</setting>
  </rule>
</root>

如果我理解 XSD 正确,这应该可以完成工作,但事实并非如此。我做错了什么?

<xs:complexType name="RuleType">
    <xs:choice>
        <xs:element name="rule" minOccurs="1" 
                    maxOccurs="unbounded" type="RuleType" />
        <xs:element name="setting" minOccurs="1"
                    maxOccurs="unbounded" type="xs:string" />
    </xs:choice>
    <xs:attribute name="condition" type="xs:string" use="required"/>
</xs:complexType>

此 XSD 将允许您的第一个示例 XML 但不允许您的第二个示例:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="rule" type="RuleType"/>

  <xs:complexType name="RuleType">
    <xs:choice>
      <xs:element name="setting" minOccurs="1" maxOccurs="unbounded" />
      <xs:element ref="rule" minOccurs="1" maxOccurs="unbounded" />
    </xs:choice>
    <xs:attribute name="condition" use="required"/>
  </xs:complexType>

</xs:schema>

像这样阅读XSD: 每个rule可以由一个或多个setting元素组成,或者一个或多个其他 rule 元素(递归)。