XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Topic Page 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Chilly GuevaraSubject: How in XSD do I reference the element in which a UNIQUE constraint is defined in?
Author: Chilly Guevara
Date: 21 Jul 2011 06:53 AM
Originally Posted: 21 Jul 2011 06:23 AM
I'm building an XML Schema and I've set up a unique value constraint on the NAME attribute of a certain element - but I'm unable to figure out which selector to use to reference the current context element (where UNIQUE is defined). Because of this, I've had to move the UNIQUE constraint to the parent element, and reference the target element from there. I'm really wanting to have the UNIQUE defined INSIDE the element it's constraining.

(two elements in question: CONFIG (parent) and INTERROGATOR (target/context), for reference)

Here is what I have in the schema:

---------------------------------------------------------------------
<xsd:element name="config">
<!-- config Element -->
<xsd:annotation id="config.doc">
<xsd:documentation xml:lang="en">DOC</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="interrogator" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:complexType>
<xsd:unique name="interrorgator-unique-name">
<xsd:selector xpath="interrogator"/>
<xsd:field xpath="@name"/>
</xsd:unique>
</xsd:element>

...

<xsd:element name="interrogator">
<!-- interrogator Element -->
<xsd:annotation id="interrogator.doc">
<xsd:documentation xml:lang="en">Documentation goes here</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:group ref="interrogator-group" minOccurs="1" maxOccurs="1"/>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="recurse" type="xsd:boolean" default="false"/>
</xsd:complexType>
</xsd:element>
---------------------------------------------------------------------

Basically, I'm wanting to have the UNIQUE constraint defined inside the INTERROGATOR element, but can't figure out what selector references the context element (the element the UNIQUE constraint is defined in) - instead, I've had to move the UNIQUE constraint into the CONFIG element (INTERROGATOR's PARENT element), and use "interrogator" as the selector.

I've used ., ./, .// to reference the context element, to no avail. The issue I have with this is, that to do it in the parent element - when an error is thrown up about the NON-uniqueness of the NAME attribute in INTERROGATOR, it says that CONFIG is complaining... which can be unclear to developers.

Not too great when it comes to XPath, but there has to be a way to set up a UNIQUE constraint with a selector that references the element that the constraint is defined in, so the error message is clear that INTERROGATOR is complaining instead of it's parent.

Here is a snippet of the XML file I'm using to test the schema:

--------------------------------------------------------------------
<config>
<interrogator name="string" recurse="false">
<interrogator.ref uri="./" idref="IDREF"/>
</interrogator>
<interrogator name="string2" recurse="false">
<interrogator.static value="string"/>
</interrogator>
<interrogator name="string2" recurse="false">
<interrogator.ref uri="./joe/"/>
</interrogator>
</config>
--------------------------------------------------------------------

Thanks for any help.

Posttop
Ivan PedruzziSubject: How in XSD do I reference the element in which a UNIQUE constraint is defined in?
Author: Ivan Pedruzzi
Date: 21 Jul 2011 12:37 PM
Unfortunately that's the way things work in XML Schema 1.0
The XPath supported by the selector is a subset of XPath 1.0

http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#coss-identity-constraint

<<"2.2 It must be an XPath expression involving the child axis whose abbreviated form is as given above.">>

An alternative apporach would be using XSLT or XQuery to assert a set of rules, here an example

Hope this helps
Ivan


==================================
XML Input

<config>
<interrogator name="a1" recurse="false"/>
<interrogator name="a2" recurse="false"/>
<interrogator name="b2" recurse="false"/>
<interrogator name="b3" recurse="false"/>
<interrogator name="b3" recurse="false"/>
<interrogator name="a1" recurse="false"/>
</config>


==================================
XQuery



declare function local:checkUnique($e as element()) as xs:string
{
let $return :=
for $i at $p in $e/interrogator
return
if ($i/preceding-sibling::interrogator[@name = $i/@name]) then
concat( "Duplicate element 'interrogator' at position " ,$p , " value ", $i/@name, "&#10;")
else ()
return string-join($return,"")
};

let $errors := local:checkUnique(/config)
return
if(count($errors) = 0) then "No assertions found"
else $errors

===============================
Output

Duplicate element 'interrogator' at position 5 value b3
Duplicate element 'interrogator' at position 6 value a1






 
Topic Page 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.