0
votes

I am trying to write a schema that will validate an XML document with the following structure:

<?xml version="1.0" encoding="UTF-8"?>
<RootElement>
  <Group1>
    <Group1Member1 value="true"/>
    <Group1Member2 value="false"/>
    <Group1Member3 value="true"/>
  </Group1>
  <Group2>
    <Group2Member1 source="INA"/>
    <Group2Member2 source="INB"/>
    <Group2Member3 source="INC"/>
    <Group2Member4 source="IND"/>
  </Group2>
  <Group3>
    <Group3Member1 source="INY"/>
    <Group3Member2 source="INZ"/>
  </Group3>
  <Group4>
    <Group4Member device="D1" maxTemp="100" hysteresis="5" />
    <Group4Member device="D2" maxTemp="120" hysteresis="2" />
    <Group4Member device="D3" maxTemp="50" hysteresis="1" />
  </Group4>
<RootElement>

The catch is that:

  • Group1, Group2, Group3, and Group4 are optional and may occur 0 or one times in any order
  • The member elements of each group may occur in any order
  • Within Group4, Group4Member may appear between 0 and 4 times, inclusive
  • Any number of arbitrary elements not shown here may appear anywhere within RootElement or any of the groups -- they and anything in their bodies are to be ignored
  • Unknown attributes within any known element must be ignored

I have put together the following XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xs:element name="RootElement">
    <xs:complexType>
      <xs:all>
        <xs:element name="Group1" maxOccurs="1">
          <xs:complexType>
            <xs:all>
              <xs:element name="Group1Member1" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="value" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="true" />
                        <xs:enumeration value="false" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Group1Member2" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="value" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="true" />
                        <xs:enumeration value="false" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Group1Member3" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="value" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="true" />
                        <xs:enumeration value="false" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
            </xs:all>
          </xs:complexType>
        </xs:element>
        <xs:element name="Group2" maxOccurs="1">
          <xs:complexType>
            <xs:all>
              <xs:element name="Group2Member1" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="source" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="INA" />
                        <xs:enumeration value="INB" />
                        <xs:enumeration value="INC" />
                        <xs:enumeration value="IND" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Group2Member2" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="source" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="INA" />
                        <xs:enumeration value="INB" />
                        <xs:enumeration value="INC" />
                        <xs:enumeration value="IND" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Group2Member3" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="source" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="INA" />
                        <xs:enumeration value="INB" />
                        <xs:enumeration value="INC" />
                        <xs:enumeration value="IND" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Group2Member4" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="source" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="INA" />
                        <xs:enumeration value="INB" />
                        <xs:enumeration value="INC" />
                        <xs:enumeration value="IND" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
            </xs:all>
          </xs:complexType>
        </xs:element>
        <xs:element name="Group3" maxOccurs="1">
          <xs:complexType>
            <xs:all>
              <xs:element name="Group3Member1" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="source" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="INY" />
                        <xs:enumeration value="INZ" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
              <xs:element name="Group3Member2" maxOccurs="1">
                <xs:complexType>
                  <xs:attribute name="source" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="INY" />
                        <xs:enumeration value="INZ" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
            </xs:all>
          </xs:complexType>
        </xs:element>
        <xs:element name="Group4" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Group4Member" maxOccurs="4">
                <xs:complexType>
                  <xs:attribute name="device" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:enumeration value="D1" />
                        <xs:enumeration value="D2" />
                        <xs:enumeration value="D3" />
                        <xs:enumeration value="D4" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                  <xs:attribute name="maxTemp" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:integer">
                        <xs:minInclusive value="0" />
                        <xs:maxInclusive value="255" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                  <xs:attribute name="hysteresis" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:integer">
                        <xs:minInclusive value="0" />
                        <xs:maxInclusive value="255" />
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:all>
    </xs:complexType>
  </xs:element>
</xs:schema>

"xmllint" is happy with a document that has no unknown tags or attributes.

When I add "<xs:any processContents="skip" minOccurs="0">" just before the "</xs:sequence>" and "</xs:all>" tags, the schema no longer flags extra (beyond 4) or invalid (bad attribute value) "<Group4Member>" elements as errors.

I'm probably doing something stupid, and there's a chance that someone can pinpoint my problem easily, so I'm asking here.

I've not yet tried the anyAttribute on this, I figure I'll get there eventually. Also, is there any way to have "<xs:all>" groups allow 0 or more (not 0 or 1) occurrences of any member element?

Thanks for your patience, and in advance for any help.

1

1 Answers

0
votes

Add the namespace attribute to the xs:any tag with values ##other or ##local. This avoids the presence of unchecked tags from your own namespace.