views:

49

answers:

1

I'm wondering if it's possible to have a schema use user-defined elements (from the XML) for its structure.

As in, as a user, I would be able to have something like:

<subjectType>
   <name>plane</name>
   <name>bird</name>
</subjectType>
<questionType>
   <name>organic</name>
   <name>awesome</name>
</questionType>
<subjectInterview subjectType="plane">
   <question questionType="organic">false</question>
   <question questionType="awesome">true</question>
</subjectInterview>
<subjectInterview subjectType="bird">
   <question questionType="organic">true</question>
   <question questionType="awesome">false</question>
</subjectInterview>

So the schema would know about:

  • subjectType
  • questionType
  • subjectInterview
  • question

but not the user-defined sub-elements. It would understand how the elements nest in relation to each other and have other restrictions (it would treat the user-defined values like enums to prevent typos and prevent duplicate questionType's per subjectType).

How would I go about getting this type of user-defined content to be enforced in a schema?

edit: If it matters, I also plan on unmarshalling the user-defined xml to java classes.

Thanks

A: 

Ok - found out that I have to use "key" and "keyref" in the schema.

First- a modified XML file:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <subjectType>
       <subject idref="plane"/>
       <subject idref="bird"/>
    </subjectType>
    <questionType>
        <question idref="organic"/>
        <question idref="awesome"/>
    </questionType>
    <subjectInterview id="plane">
       <question id="organic">false</question>
       <question id="awesome">true</question>
    </subjectInterview>
    <subjectInterview id="bird">
       <question id="organic">true</question>
       <question id="awesome">false</question>
    </subjectInterview>
</root>

and here's the schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="subjectType" type="subjectType" maxOccurs="unbounded"/>
                <xs:element name="questionType" type="questionType" maxOccurs="unbounded"/>
                <xs:element name="subjectInterview" type="subjectInterview" maxOccurs="unbounded">
                    <xs:key name="questionID">
                        <xs:selector xpath="./question"/>
                        <xs:field xpath="@id"/>
                    </xs:key>

                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="subjectID">
            <xs:selector xpath="./subjectInterview"/>
            <xs:field xpath="@id"/>
        </xs:key>
        <xs:keyref name="subjectIDref" refer="subjectID">
            <xs:selector xpath="./subjectType/subject"/>
            <xs:field xpath="@idref"/>
        </xs:keyref>

        <xs:keyref name="questionIDref" refer="questionID">
            <xs:selector xpath="./questionType/question"/>
            <xs:field xpath="@idref"/>
        </xs:keyref>
    </xs:element>

    <xs:complexType name="subjectInterview">
        <xs:sequence  maxOccurs="unbounded">
            <xs:element name="question" type="question"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="question">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="id" type="xs:string"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="subjectType">
        <xs:sequence>
            <xs:element name="subject" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="idref" type="xs:string"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="questionType">
        <xs:sequence>
            <xs:element name="question" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="idref" type="xs:string"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

Should be a decent base for people trying to do the same.

Marc