My goal is to have a RELAX NG compact schema which enforces that an element's datatype matches that of the parent element's datatype.
I currently have the following schema:
start = Tickmarks
Tickmarks = element tickmarks {
attribute from { xsd:float | xsd:date },
attribute to { xsd:float | xsd:date },
Tick*
}
Tick = element tick {
attribute value { xsd:float | xsd:date },
attribute label { text }
}
What I would like is a schema that describes a document where by if Tickmarks/@from is a float, Tickmarks/Tick/@value must also be a float.
So essentially it should satisfy the following tests:
VALID
<tickmarks from="1" to="10">
<tick value="3" label="3"/>
<tick value="7" label="7"/>
</tickmarks>
VALID
<tickmarks from="2000-01-01" to="2006-01-01">
<tick value="2002-01-01" label="2002"/>
<tick value="2004-01-01" label="2004"/>
</tickmarks>
INVALID
<tickmarks from="2000-01-01" to="2006-01-01">
<tick value="10" label="10"/>
<tick value="20" label="20"/>
</tickmarks>
INVALID
<tickmarks from="1" to="10">
<tick value="2002-01-01" label="2002"/>
<tick value="2004-01-01" label="2004"/>
</tickmarks>
Is this possible with RELAX NG compact?
If you want to stay with pure RELAX NG (and avoid alternative solutions like embedded Schematron rules), you could use:
start = Tickmarks
Tickmarks = element tickmarks {
(
attribute from { xsd:float },
attribute to { xsd:float },
Tick-float*)
| (
attribute from { xsd:date },
attribute to { xsd:date },
Tick-date*)
}
Tick-float = element tick {
attribute value { xsd:float },
attribute label { text }
}
Tick-date = element tick {
attribute value { xsd:date },
attribute label { text }
}