- From: Jeni Tennison <jeni@jenitennison.com>
 - Date: Fri, 30 Aug 2002 11:20:03 +0100
 - 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 UTC