W3C home > Mailing lists > Public > xmlschema-dev@w3.org > August 2002

Re: an Schema for this xml?

From: Jeni Tennison <jeni@jenitennison.com>
Date: Fri, 30 Aug 2002 11:20:03 +0100
Message-ID: <1401543807688.20020830112003@jenitennison.com>
To: xmlschema-dev@w3.org, "Marcos Mayorga" <marcos.mayorga@grupotecnobit.com>

Hi Marcos,

> how can write an schema where an element has two ways of be
> described?

You can't, I'm afraid, not using W3C XML Schema, at least not if the
element appears with the two different types in the same content
model. W3C XML Schema has a constraint that says that in a particular
content model, all the element particles with a particular name must
have the same type as well. It also doesn't have the facility of
allowing element content to be determined by what attributes are there
or not (co-occurrence constraints).

You can specify a general type for the element that covers both your
possibilities:

  <xs:element name="myelement">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element ref="mynestedelement" minOccurs="0" />
      </xs:sequence>
      <xs:attribute name="name" type="xs:NMTOKEN" />
      <xs:attribute name="a" type="xs:integer" />
      <xs:attribute name="b" type="xs:integer" />
      <xs:attribute name="href" type="xs:anyURI" />
      <xs:attribute name="path" type="xs:token" />
    </xs:complexType>
  </xs:element>

and then have a separate Schematron rule that tests the combinations,
for example:

  <sch:rule context="myelement">
    <sch:assert test="(@name and @a and @b and mynestedelement and
                       not(@href) and not(@path)) or
                      (@href and @path and
                       not(@name) and not(@a) and not(@b) and not(*))">
      "myelement" elements must either have a name, a and b attributes
      and a mynestedelement child or have an href and a path
      attribute.
    </sch:assert>
  </sch:rule>

Or you can switch to a different schema language, such as RELAX NG,
which does support this kind of thing:

  <element name="myelement">
    <choice>
      <group>
        <attribute name="name"><data type="xs:NMTOKEN" /></attribute>
        <attribute name="a"><data type="xs:integer" /></attribute>
        <attribute name="b"><data type="xs:integer" /></attribute>
        <ref name="mynestedelement" />
      </group>
      <group>
        <attribute name="href"><data type="xs:anyURI" /></attribute>
        <attribute name="path"><data type="xs:token" /></attribute>
        <text />
      </group>
    </choice>
  </element>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/
Received on Friday, 30 August 2002 06:20:04 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 11 January 2011 00:14:34 GMT