问题描述:

I have xml file that seems like that

<doc>

<field name="simple_meta">book</field>

<field name="complex_meta">journal</field>

<field name="text_date">some text</field>

</doc>

I would like to validate element text by pattern based on value in attribute "name". that is, if the value of attribute is "simple_meta" I want to make the "simpleRestriction" validation, in case of the "complex_meta" to make the "complexRestriction" validation. The problem is that I cannot define element with same name under the same node. Can someone to help me to resolve this problem?

<xs:schema ......>

<xs:simpleType name="simpleRestriction">

<xs:restriction base="xs:string">

<xs:maxLength value="20"/>

</xs:restriction>

</xs:simpleType>

<xs:simpleType name="complexRestriction">

<xs:restriction base="xs:string">

<xs:maxLength value="10"/>

<xs:pattern value="([\w])*"/>

</xs:restriction>

</xs:simpleType>

<xs:element name="str">

<xs:complexType>

<xs:simpleContent>

<xs:extention base="simpleRestriction">

<xs:attribute name="name">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:pattern value="simple_meta"/>

</xs:restriction>

</xs:simpleType>

</xs:attribute>

</xs:extention>

</xs:simpleContent>

</xs:ComplexType>

</xs:element>

<xs:element name="str">

<xs:complexType>

<xs:simpleContent>

<xs:extention base="complexRestriction">

<xs:attribute name="name">

<xs:simpleType>

<xs:restriction base="xs:string">

<xs:pattern value="complex_meta"/>

</xs:restriction>

</xs:simpleType>

</xs:attribute>

</xs:extention>

</xs:simpleContent>

</xs:ComplexType>

</xs:element>

</xs:schema>

网友答案:

The short answer is: don't do that.

XSD is designed to validate elements based primarily (and in the simple case exclusively) on the element's name. If you have three different validation logics, then you will do better to tell the XSD validator that there are three types of elements (named, perhaps, simple_meta, complex_meta, and test_date) instead of claiming implausibly that there is just one type of element. Use a common base type to make the relation among the types of the three elements explicit, or a common substitution group to relate the three element types themselves.

If you really have to do that, or if you really know what you're doing and want to do that (I'm not sure that combination is possible, but I'll try to be broad-minded here), your basic options are:

  • use xsi:type in the instance to specify the type of each element in the instance (roughly similar to your name attribute, but names a type declared in the schema)

  • use XSD 1.1 and conditional type assignment

  • use XSD 1.1 and assertions

Or leave XSD behind:

  • use Schematron and assertions

  • use RelaxNG and write the different values of the attribute into the content model

相关阅读:
Top