XML Schema Definitions

L

Lemon Tree

Hello everybody.

I have a problem with Schema Definitions and I cannot figure out how to
solve it (provided that it could be solved :)) Here we go...

Let's suppose to have a simple XML file with the following tags:

<type id="id1"/>
<type id="id2"/>
<type id="id3"/>

Now I would like to express, by using an XSD, the following restriction
on a tag attribute: the value of the attribute must be the value of the
id attribute of some previously defined <type> tag.

For example, let's suppose to have a <foo> tag with a "type" attribute.
Then the admissible values for the "type" attribute would be id1, id2
or id3.

At the beginning I thought it was not possible but, while I was writing
an XSD I noticed that I was doing the previously described thing all
the time!!! In fact, my XSD are full of type declarations like

<xs:complexType name="myTypeName">
...
</xs:complexType>

and these declarations are used to define the type of elements, for
example

<xs:element type="myTypeName"> ...

The validator complains if the value of the "type" attribute has not
been previously defined
That's exactly the thing I would like to do with my XML files :)

I saw the XSD of the XSD but it is too complicated and by looking at it
I cannot understand if this kind of enforcement (using declared types)
can be embedded in the XSD itself or it is part of an ad-hoc logic of
the validator program.

I still think that it is not possible to enforce such a kind of
restriction by simply using XSD files but I might be wrong. Any hint?

Thank you
 
M

Martin Honnen

Lemon Tree wrote:

Let's suppose to have a simple XML file with the following tags:

<type id="id1"/>
<type id="id2"/>
<type id="id3"/>

Now I would like to express, by using an XSD, the following restriction
on a tag attribute: the value of the attribute must be the value of the
id attribute of some previously defined <type> tag.

For example, let's suppose to have a <foo> tag with a "type" attribute.
Then the admissible values for the "type" attribute would be id1, id2
or id3.

Look into xs:key and xs:keyref, you define those id attributes as keys
on the type element, then you define a keyref for the foo element so
that the type attribute on foo is a key reference.

Example and introduction is here:
<http://www.w3.org/TR/xmlschema-0/#specifyingKeysAndtheirRefs>
<http://www.w3.org/TR/xmlschema-0/#report.xsd>


If those id attributes are unique in the complete XML document then you
could also use xs:ID as the id attribute type for your type element and
xs:IDREF for the foo attributes.
 
L

Lemon Tree

Martin Honnen ha scritto:
Example and introduction is here:
<http://www.w3.org/TR/xmlschema-0/#specifyingKeysAndtheirRefs>
<http://www.w3.org/TR/xmlschema-0/#report.xsd>


If those id attributes are unique in the complete XML document then you
could also use xs:ID as the id attribute type for your type element and
xs:IDREF for the foo attributes.
Thank you for you help.
I will profit a bit of this thread to ask another thing... I was
experimenting with what it is written in the document cited before. In
particular I was trying to use the <unique> tag.

Now I am using Xerces to validate the XML against the schema, but it
doesn't work.
I cannot tell if it is an error in the Schema or if Xerces is unable to
check this kind of constraints.

Here it is the XSD and the XML:

* XSD
****************************************************************************************************

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.xnemesis.org"
xmlns="http://www.xnemesis.org"
elementFormDefault="qualified">

<xs:complexType name="resourceType">
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="type" type="xs:string"/>
</xs:complexType>

<xs:element name="declarations">
<xs:complexType>
<xs:sequence>
<xs:element name="resource" type="resourceType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

<xs:unique name="dummy">
<xs:selector xpath="resource"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>

</xs:schema>

* XML
**********************************************************************************************************

<?xml version="1.0"?>
<declarations xmlns="http://www.xnemesis.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.xnemesis.org
declaration.xsd">

<resource id="id" type="type"/>
<resource id="id" type="type"/>
<resource id="id" type="type"/>
<resource id="id" type="type"/>

</declarations>
***********************************************************************************************************

I cannot see anything wrong with the previous files but the XML is
recognized as valid while the <unique> element in the XSD should
prevent the declaration of many <resource>s with the same id.

Any hint?
Thank you
 
M

Martin Honnen

Lemon Tree wrote:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.xnemesis.org"
xmlns="http://www.xnemesis.org"
Add
xmlns:xn="http://www.xnemesis.org"
here


<xs:element name="declarations">
<xs:complexType>
<xs:sequence>
<xs:element name="resource" type="resourceType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

<xs:unique name="dummy">
<xs:selector xpath="resource"/>

Then you need e.g.
<xs:selector xpath="xn:resource" />

as your elements are in a namespace and XPath nodes tests like resource
select/match elements in no namespace whereas with xn:resource and the
above namespace declaration the XPath selects/matches resource elements
in the namespace with the URI http://www.xnemesis.org. You don't have to
change anything in the XML instance documents you want to validate.
 
G

George Bina

The schema constraint looks for resource elements from no namespace
while you have in your document resource elements from the
http://www.xnemesis.org namespace. Note that the XPath subset from the
XML Schema as well as XPath 1.0 has no notion of default namespace,
name tests without a prefix are considered to be from no namespace. You
should change your schema as below:


<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.xnemesis.org"
xmlns="http://www.xnemesis.org"
xmlns:t="http://www.xnemesis.org"
elementFormDefault="qualified">

<xs:complexType name="resourceType">
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="type" type="xs:string"/>
</xs:complexType>

<xs:element name="declarations">
<xs:complexType>
<xs:sequence>
<xs:element name="resource" type="resourceType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

<xs:unique name="dummy">
<xs:selector xpath="t:resource"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>

</xs:schema>

Best Regards,
George
 
L

Lemon Tree

I thank you all for your helpful suggestions.
Now it works perfectly!

Thank you again
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top