XSD验证元素取决于父节点

时间:2014-09-08 08:30:29

标签: xml xsd

<a>可以包含文字和<i>代码,<i>可以包含文字和<a>代码。

<a>lol<i>so rad</i></a> - valid
<i>so sweet <a>lolz</a></i> - valid

我当前的解决方案存在严重缺陷,下一个是“有效”,cos <a>包含在<i>中。

<a>so what now <i>so sweet <a>lolz</a></i></a>

我想测试<i>元素父元素,因此如果它位于<a>标记内,我可以禁止<a>子元素。

当前XSD:

<xs:element name="a">
  <xs:complexType>
     <xs:complexContent>
        <xs:extension base="bodyMixed">
          <xs:attribute name="href" type="xs:anyURI" use="required" />
          <xs:attribute name="target" type="xs:string" />
        </xs:extension>
      </xs:complexContent>
     </xs:complexType>
</xs:element>

<xs:complexType name="bodyMixed" mixed="true">
    <xs:group ref="fontStyle" minOccurs="0" maxOccurs="unbounded"/>
</xs:complexType>

<xs:complexType name="basic" mixed="true">
   <xs:sequence>
      <xs:element ref="a" minOccurs="0" maxOccurs="unbounded"/>
   </xs:sequence>
</xs:complexType>

<xs:group name="fontStyle">
    <xs:choice>
       <xs:element name="i" type="basic"/>
    </xs:choice>
</xs:group>

1 个答案:

答案 0 :(得分:1)

处理这种情况的最简单方法是使用Schematron或XSD 1.1中的断言。由于XSD断言无法在树中查找,因此您需要为a编写一个断言,断言所讨论的a元素没有名为a的后代。因此,它是外a,而不是内a,它将无效。 (Schematron对于断言可以引用的内容不那么挑剔,因此您可以轻松编写Schematron规则来使内部{而不是外部ai内的a成为无效。)

如果您无权访问断言(例如,因为您使用的是XSD 1.0),则需要使用本地元素声明提供的有限上下文感知,并在this old XSD working paper中进行描述。