[Schematron] uniqueness help and an extreme case of constraints.

Adam De Witt adewitt at prg.com
Thu Nov 20 13:28:40 EST 2008


I am very new to XML, having just recently fully grasped Relax NG, and  
now Schematron is really kicking my butt. The following is a watered  
down example of what im working with.

<profile>
	<params>
		<param param_name="Alpha" label="Foo" channel="1" />
		<param param_name="Beta" label="Bar" channel="2" />
	</params>
	<values>
		<value_range param_name="Alpha" id="alpha_list_1" range="0 99">
			<value range="0 7" position="1" id="alpha_list_1_default" />
			<value range="8 25" position="2" />
			<value range="26 44" position="3" />
			<value range="45 63" position="4" />
			<value range="64 82" position="5" />
			<value range="83 99" position="6" />
		</value_range>
		<value_range param_name="Alpha" id="alpha_list_2" range="100 216" >
			<value range="100 116" position="1" id="alpha_list_2_default" />
			<value range="117 134" position="2" />
			<value range="135 153" position="3" />
			<value range="154 172" position="4" />
			<value range="173 191" position="5" />
			<value range="192 209" position="6" />
		</value_range>
	</values>
</pofile>

There are a number of items I need to verify here with ISO Schematron  
that I just can not get working properly.
For starters, I have a number of unique attribute values to assert. An  
@param_name value can only be specified once within the /profile/ 
params element, An @channel value can only be specified once within  
the /profile/params element, and an @position value can only be  
specified once within its /profile/values/value_range element.

A @param_name under /profile/values/value_range must reference one  
defined in any of the /profile/params/param elements.

The worst of all, @range values must be numerically unique between  
sibling value or value_range elements.  eg  <value range="0 7"> and  
<value range="5 15"> within the same parent should be invalid.  Im not  
quite sure if this is even possible, as you would need to calculate  
two different whitespace separated numbers within the same attribute  
value.  As well, the /profile/values/value_range/value/@range values  
should be within the parent value_range's @range.  From what I can  
understand, this is simply impossible with Schematron.

This is an example of two of my horribly failed attempts to get the  
uniqueness asserted:
<pattern>
	<rule context="/profile/params">
		<assert test="count(param/@param_name[. = current()] = 1)">
			Duplicate '<value-of select="@param_name" />'
			param_name exists.
			param_names should be unique.
		</assert>
	</rule>
</pattern>
<pattern>
	<rule context="profile/values/value_range/value/@position">
		<assert test="count(//@position[. = current()]) = 1"> Position not  
unique! </assert>
	</rule>
</pattern>

I have pieced those two ideas together from examples ive found, but  
neither work in oXygen for me.


Any guidance would be greatly appreciated.

cheers,
-Adam



More information about the Schematron mailing list