Re: Attribute type in XMLSchema

Hi Stamatis,

> Hi. I found out that my problem is a bit more complicated than this.
> I want(if possible) to create attributes that will take as a value
> in the xml file an actual xml schema datatype. Check out this xml
> instance:
>
> <param name="lala" type="xs:string">stamatis</param>
> <param name="lala2" type="xs:int">0</param>
>
> Not only the attribute type must be of xml schema type but the element's
> value must be of the same type so for the xml file to be valid. Is this
> feasible?

This is a bit tricky. The only way that you can do co-occurrence
constraints (where the value of an attribute changes what's legal for
an element) in XML Schema is by using the xsi:type attribute to
specify the type of the element. For example, you can make:

  <param xsi:type="xs:string">stamatis</param>
  <param xsi:type="xs:int">0</param>

work very easily. However, if you add the name attribute to the
<param> elements:

  <param name="lala" xsi:type="xs:string">stamatis</param>
  <param name="lala2" xsi:type="xs:int">0</param>

then it's no longer true that the type of the first <param> element is
xs:string because a <param> element of type xs:string can't have a
name attribute.

I can see two ways around this -- assuming you're prepared to change
your XML. One is to change it so that the <param> element holds a
<value> element, and it's the xsi:type attribute on the <value>
element that determines the type of the content:

  <param name="lala"><value xsi:type="xs:string">stamatis</value></param>
  <param name="lala2"><value xsi:type="xs:int">0</value></param>

The other is to create your own types that mimic the XML Schema types
that you want to use, but have a name attribute as well. For example,
the following works (at least with MSXML4):

<xs:complexType name="paramType" abstract="true">
  <xs:simpleContent>
    <xs:extension base="xs:anySimpleType">
      <xs:attribute name="name" type="xs:string" use="required" />
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>

<xs:complexType name="string">
  <xs:simpleContent>
    <xs:restriction base="paramType">
      <xs:simpleType>
        <xs:restriction base="xs:string" />
      </xs:simpleType>
    </xs:restriction>
  </xs:simpleContent>
</xs:complexType>

<xs:complexType name="int">
  <xs:simpleContent>
    <xs:restriction base="paramType">
      <xs:simpleType>
        <xs:restriction base="xs:int" />
      </xs:simpleType>
    </xs:restriction>
  </xs:simpleContent>
</xs:complexType>

<xs:complexType name="float">
  <xs:simpleContent>
    <xs:restriction base="paramType">
      <xs:simpleType>
        <xs:restriction base="xs:float" />
      </xs:simpleType>
    </xs:restriction>
  </xs:simpleContent>
</xs:complexType>

<xs:element name="param" type="paramType" />

and allows:

  <param name="lala" xsi:type="string">stamatis</param>
  <param name="lala2" xsi:type="int">0</param>

but doesn't allow:

  <param name="lala2" xsi:type="int">rubbish</param>

for example.

Of course whether you're prepared to change your markup language to
such an extent, and declare all those types in your schema, is up to
you. If you're not, then you can't do what you want in XML Schema. You
might try using another schema language, such as RELAX NG, in which
it's pretty easy:

  <element name="param">
    <attribute name="name" />
    <choice>
      <group>
        <attribute name="type">
          <value type="QName">xs:string</value>
        </attribute>
        <data type="string" />
      </group>
      <group>
        <attribute name="type">
          <value type="QName">xs:int</value>
        </attribute>
        <data type="int" />
      </group>
      <group>
        <attribute name="type">
          <value type="QName">xs:float</value>
        </attribute>
        <data type="float" />
      </group>
    </choice>
  </element>
  
Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Received on Tuesday, 1 July 2003 06:30:52 UTC