通过XML Schema限制元素组中的值

时间:2011-01-04 15:14:30

标签: regex validation xsd

我有限制设置元素的值。根据我想要设置的规则,我的元素可以使用以下值。

<tags>
    <tag>One of Audio, Video, Others.</tag>
    <tag>For Audio, either Label or Record, For Video, either Studio or Producer, For Others this tag will be empty.</tag>
    <tag>One of English, Spanish, French</tag>
</tags>

现在我可以在我的XSD中为单个标签元素设置正则表达式模式限制,如果它是纯文本分隔符(,)分隔值,可能是

<element name="tags">
    <simpleType>
        <restriction base="string">
            <pattern value="(Audio, (Label|Record)|Video, (Studio|Producer)|Others), (English|Spanish|French)" />
        </restriction>
    </simpleType>
</element>

但由于我有一系列同名tag的元素,我不确定是否有可能通过XSD限制这种方式。我知道我可以通过enumeration来限制值,但我无法对这些值进行分组。我想跟随XML来验证

<tags>
    <tag>Audio</tag>
    <tag>Record</tag>
    <tag>English</tag>
</tags>

以及验证失败

<tags>
    <tag>Others</tag>
    <tag>Record</tag>
    <tag>English</tag>
</tags>

我的实际情况比嵌套限制要复杂得多,但我有人可以在上述情况下提供帮助,我想我可以把它作为参考并解决我的问题。

1 个答案:

答案 0 :(得分:1)

我认为你不能。如果您可以控制架构,为什么还需要这个特定的规则集进行验证?如果您需要以这种方式进行严格验证,则可能需要在应用程序级别而不是文档定义级别完成。看起来你真正想要的是一种基于某些标签“类型”标记不同信息的方法。实际上没有理由让所有名为tag的元素列表,你知道它们已经是来自父元素名称的标签。相反,如果您希望基于标记类型进行验证,则应使用不同的元素类型并构建模式,以验证何时何地允许使用哪些类型。对于您的数据,可以使用复杂类型和选择模型来完成:

  <xs:element name="audio">
    <xs:complexType>
      <xs:choice>
        <xs:element name="Label" type="xs:string"/>
        <xs:element name="Record" type="xs:string"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="generic">
    <xs:choice>
      <xs:element name="Studio" type="xs:string"/>
      <xs:element name="Producer" type="xs:string"/>
    </xs:choice>
  </xs:complexType>

  <xs:element name="video" type="generic"/>
  <xs:element name="other" type="generic"/>

  <xs:element name="tags">
    <xs:complexType>
      <xs:sequence>
        <xs:choice>
          <xs:element ref="audio"/>
          <xs:element ref="video"/>
          <xs:element ref="other"/>
        </xs:choice>
        <xs:element name="language">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="English"/>
              <xs:enumeration value="Spanish"/>
              <xs:enumeration value="French"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

我冒充生产者,标签,工作室和记录,你也想要这些类型的价值。如果没有,对于原始情况,您可以在父元素上使用属性,如下所示:

  <xs:complexType name="generic">
    <xs:attribute name="meta-type">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Studio"/>
          <xs:enumeration value="Producer"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

您可以使用substitutionGroups而不是使用选择组,但这需要从您可能不需要的相同类型派生每个元素。

这些架构可以很容易地扩展,如果你仍然需要一个不需要严格验证的通用&lt; tag&gt;列表,你可以将它作为标签序列定义的一部分添加。

也许有人可以为您的原始要求提供更好的答案,但我希望这些信息有所帮助。