xmlxsdxercesxsd-1.1xsd-1.0

Validate tag inside unknown/ignored tag or under multiple hierarchies?


I have an XML file with multiple unknown tags that contains known tags to which validation should be added.

<root>
  <child>
    <template id="abc"/>
  </child>
  <child>
    <random>
      <template id="abc"/>
    </random>
  </child>
</root>

The random tag represents an unknown random tags represented by xs:any, I moved to XSD 1.1 to allow having:

<xs:choice>
   <xs:element name="child" type="xs:string">
        <xs:complexType>
           <xs:sequence>
              <xs:element name="template" type="xs:string">
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="xs:string">
                            <xs:attribute name="id" use="optional">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:pattern value="[a-z]"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:attribute>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
              </xs:element>
              <xs:any/>
           </xs:sequence>
       </xs:complexType>    
   </xs:element>
  <xs:any/>
</xs:choice>

My problem is that known tags such as template and child occur inside unknown tags, and under unknown hierarchy of known and unknown tags.

Is there a way xs:any can contain known tags or to add validation for known tags and ignore hierarchy, so errors inside known tags would be checked under any hierarchy ?

Any solution in XSD 1.1 or XSD 1.0 is welcomed.


Solution

  • As long as you can anticipate the set of allowed elements, xs:any/@processContents="lax" will allow you to constrain their content models.

    Alternatively, you can have xsd:any allow unknown tags by specifying @processContents="skip", but once you do that, you lose all ability to specify further constraints on those elements, except via xs:assert.

    If you can craft your constraints in terms of xs:assert XPaths, you'll be fine. However, you cannot, as it sounds like you're hoping to be able to do, have a hybrid of xs:any/@processContents="skip" followed by xs:any/@processContents="lax" or xs:any/@processContents="strict" for descendents of the skipped element. (If you start with @processContents="lax", you can always use xs:any/@processContents="skip" deeper in the hierarchy, of course, but not the other way around.)

    See also: processContents strict vs lax vs skip for xsd:any.