Link to home
Start Free TrialLog in
Avatar of maverick65
maverick65

asked on

XSD keyref problem

I want to write an XSD, which accepts the following XML File:

<root>
<types>
<type name="type1"/>
<type name="type2"/>
</types>
<items>
<item name="n1" type="type1"/>
<item name="n2"  type="standardtype1"/>
<item name="n3"  type="standardtype1"/>
<item name="n4"  type="type1"/>
<item name="n5"  type="type2"/>
<item name="n6"  type="standardtype2"/>
</items>
</root>

The problem that I have is the attribute "type" of the item element. Acceptable values for this attribute are the names of the defined types. Additionally, it should accept a list of standard types (lets them call standardtype1 and standardtype2) which do not occure in the XML File.

How can I define such an attribute in an XSD?
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Hi maverick65,
> <type name="type2"/>

The following schema does the key/keyref bit

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="types"/>
                <xs:element ref="items"/>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="TypeName">
            <xs:selector xpath="types/type"/>
            <xs:field xpath="@name"/>
        </xs:key>
        <xs:keyref refer="TypeName" name="ItemName">
            <xs:selector xpath="items/item"/>
            <xs:field xpath="@type"/>
        </xs:keyref>
    </xs:element>
   
    <xs:element name="types">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
                <xs:element ref="type"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
   
    <xs:element name="type">
        <xs:complexType>
            <xs:attribute name="name" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="items">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
                <xs:element ref="item"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="item">
        <xs:complexType>
            <xs:attribute name="name" use="required"/>
            <xs:attribute name="type" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

>Additionally, it should accept a list of standard types (lets them call standardtype1 and standardtype2) which do not occure in the XML File
I am afraid this cannot be done using the key/keyref mechanisms in W3C schema
you either force the attribute to be a referer to the attribute values in your typelist
or you leave it open,
a combination sounds kinda weird

Can you not force these two extra type dfinitions in the document before validation
(in some sort of transformation preprocess)
that would be handier I guess

You can also try to use schematron instead...
you would be able to express this requirement in schematron (www.schematron.org)

cheers

Cheers!
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I don't think it can be done. We can capture the user-defined types with ID, as in

<!ELEMENT type EMPTY>
<!ATTLIST type name ID #REQUIRED>


And we could enumerate the built-in types, but this gives us two different kinds of information - and I can't find a way for one attribute to have two different types.

I'm hoping to be corrected...

David
David,

> I don't think it can be done
nope, not with schema, certainly not with DTD
likely with schematron,
but in stead of schematron you could build a validation layer using XSLT, that does what is needed

> We can capture the user-defined types with ID

well, ID/IDREF is the DTD way of doing KEY/KEYREF
the later is more powerfull because it can eg. capture element content as the ID
or can combine values as the "ID"
none of this is neede though, so the ID/IDREF mechanism of W3C schema could be used

I don't recommend using ID/IDREF in schema though,
because its only purpose of existense is pleasing the DTD people (so some sort of backwards compatibility if you like)
since this seems a brand new project and W3C schema was somehow mentioned as a requirement, forget about ID/IDREF

> and I can't find a way for one attribute to have two different types

you can't do what you are trying here

cheers

Geert