1
votes

An XML document is as follows:

<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://localhost/app/myschema.xsd myschema.xsd">
    <metadata>
        <source appVer="2.10.0.3" structure="2.10.18.34" sequence="00000001" dt="2014-08-26T11:13:15"/>
    </metadata>
    <firstItemStorage>
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
    </firstItemStorage>
    <secondItemStorage>
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
    </secondItemStorage>
    <anyOtherElement>
        <!-- Any XML -->
    </anyOtherElement>
</data>

I would like to define following:

  • A document's root element must be data.
  • Inside of it there could be any elements in any order.
  • metadata element is mandatory and has a strict structure.
  • Any other elements are not required and nave loose structure.
  • When elements like firstItemStorage and secondItemStorage are defined in XSD schema and occur in XML document, they should be validated to have zero or unlimited row elements which have zero or unlimited attributes in any order. Defined attributes are validated, undefined are prohibited.
  • when any other elements that are not defined in XSD schema occur in XML document, no validation error happens and contents of them is not validated.

My schema for it is as follows:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="data">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="metadata" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="source">
                <xs:complexType>
                  <xs:attribute name="appVer" type="xs:string" use="required"/>
                  <xs:attribute name="structure" type="xs:string" use="required"/>
                  <xs:attribute name="sequence" type="xs:unsignedInt" use="required"/>
                  <xs:attribute name="dt" type="xs:dateTime" use="required"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="firstItemStorage" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="row" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <!-- Attributes could have any order -->
                  <xs:attribute name="id" type="xs:int" />
                  <xs:attribute name="sid" type="xs:int" />
                  <xs:attribute name="id_group" type="xs:int" />
                  <xs:attribute name="consum" type="xs:double" />
                  <xs:attribute name="overloadlimit" type="xs:double" />
                  <xs:attribute name="upd" type="xs:dateTime" />
                  <!-- Any other attributes are prohibited -->
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="secondItemStorage" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="row" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <!-- Attributes could have any order -->
                  <xs:attribute name="id" type="xs:int" />
                  <xs:attribute name="meaning" type="xs:string" />
                  <xs:attribute name="visible" type="xs:boolean" />
                  <xs:attribute name="a_counter" type="xs:boolean" />
                  <xs:attribute name="activities" type="xs:boolean" />
                  <xs:attribute name="upd" type="xs:dateTime" />
                  <!-- Any other attributes are prohibited -->
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <!-- Any other elements are allowed, but not validated -->
        <xs:any />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

I have problems with xs:any element:

  • The any element allows not only any unknown elements, but also any attributes of known elements
  • I get a warning from Visual Studio:

Warning 26 Wildcard '##any' allows element 'operations', and causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence.

Without any element I gen an error when elements not defined in XSD occur in XML document.

How to define safely what I want to?

1

1 Answers

1
votes

In XSD 1.1, you don't get any ambiguity between a specific element particle and a wildcard particle; the specific particle has higher priority. You're going to find it much easier to meet your requirements if you move to XSD 1.1 (which means using non-Microsoft tools).

If you're prepared to constrain the metadata element to come first, then you can do this (even in XSD 1.0) with a content model of (metadata, xs:any*), where the xs:any has processContents="lax". Lax validation basically means if there's a global element declaration, then validate against it, otherwise, don't validate. Your firstItemStorage and secondItemStorage element declarations then have to become global element declarations (xs:element as a child of xs:schema).

Moving to XSD 1.1 enables you to lift the restriction that the metadata must come first (I'm not sure if you want to restrict it to only appear once).