XSD重用元素选择而不包装它

时间:2017-09-05 16:22:55

标签: xml types xsd xsd-validation xml-validation

我需要为包含递归表达式树的XML编写XSD:

<binary op="plus">
  <var>X</var>
  <const>5</const>
</binary>

其中操作数总是可以是var,const,call,unary,binary中的任何一个,所以例如这些也是有效的:

<binary op="divide">
  <const>2</const>
  <const>2</const>
</binary>

<binary op="plus">
  <call>f</call>
  <binary op="minus">
    <var>Y</var>
    <var>Y</var>
  </binary>
</binary>

我想以某种方式定义const,var,call,unary,binary 在一个地方中的选择,以限制冗余。我可以使用命名类型执行此操作,但只能使用其他包装/嵌套:

<binary op="plus">
  <operand><call>f</call></operand>
  <operand><var>Y</var></operand>
</binary>

这不是必需的。是否可以为原始格式定义简洁 XSD,即没有<operand />的额外级别?

1 个答案:

答案 0 :(得分:1)

使用element substitution group ...

XSD

此XSD将根据请求成功验证所有三个示例XML文档,而不包含operand包装:

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

  <xs:element name="binary" substitutionGroup="TermSubGroup">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="TermSubGroup"
                    minOccurs="2" maxOccurs="2"/>
      </xs:sequence>
      <xs:attribute name="op" type="xs:string"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="TermSubGroup" abstract="true"/>

  <xs:element name="var" type="TermGroup" substitutionGroup="TermSubGroup"/>
  <xs:element name="const" type="TermGroup" substitutionGroup="TermSubGroup"/>
  <xs:element name="call" type="TermGroup" substitutionGroup="TermSubGroup"/>

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

</xs:schema>