Soren said:
That's not expressible as a regular tree language, so Relax NG can't
express it either. In fact, no schema language that I know of can
express it.
Soren
hi,
you should consider an alternate schema technology, such as Active Schema :
the schema :
====================== schema.asl
<?xml version="1.0" encoding="iso-8859-1" ?>
<asl:active-schema
xmlns:xcl="
http://www.inria.fr/xml/active-tags/xcl"
xmlns:asl="
http://www.inria.fr/xml/active-schema"
xmlns:xs="
http://www.w3.org/2001/XMLSchema-datatypes"
target=""
<asl:element name="test" root="always">
<asl:sequence>
<asl:element ref-elem="table" min-occurs="0"
max-occurs="unbounded"/>
</asl:sequence>
</asl:element>
<asl:element name="table">
<asl:sequence>
<asl:element ref-elem="column" min-occurs="1"
max-occurs="unbounded"/>
</asl:sequence>
</asl:element>
<asl:element name="column">
<asl:sequence>
<xcl:if test="{ asl:element()/preceding-sibling::column }">
<xcl:then>
<asl:element ref-elem="cell" min-occurs="{
$asl:max-occurs }" max-occurs="{ count( asl:element()/../column[1]/cell
) }"/>
</xcl:then>
<xcl:else>
<asl:element ref-elem="cell" min-occurs="1"
max-occurs="unbounded"/>
</xcl:else>
</xcl:if>
</asl:sequence>
</asl:element>
</asl:active-schema>
=====================
as you might guess, the Active Schema Language differs slightly from
other schema technologies : most things that are usually hard-coded in
the schema can be defined contextually
-boundaries can be computed dynamically
-content models can also be computed dynamically
-you can mix declarative sentences with imperative instructions
-the specification defines only 20 tags
-and much more...
notice that unlike schematron, ASL computes content models, which allows
tools such as editors to predict which element is allowed ; schematron
is not predictive, it can only warn that a rule has not been followed
AFTER the user has made the mistake, for example by inserting an element
that is not allowed
the datas :
===================== datas.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<test>
<!--good-->
<table>
<column>
<cell/>
<cell/>
</column>
<column>
<cell/>
<cell/>
</column>
</table>
<table>
<column>
<cell/>
<cell/>
<cell/>
</column>
<column>
<cell/>
<cell/>
<cell/>
</column>
<column>
<cell/>
<cell/>
<cell/>
</column>
</table>
<!--bad-->
<table>
<column>
<cell/>
<cell/>
</column>
<column>
<cell/><!--cell missing-->
</column>
</table>
<table>
<column>
<cell/>
<cell/>
</column>
<column>
<cell/>
<cell/>
</column>
<column>
<cell/>
<cell/>
<cell/><!--too much cell-->
</column>
<column>
<cell/><!--cell missing-->
</column>
</table>
<table>
<!--no column ???-->
<cell/><!--oops-->
<cell/><!--oops-->
</table>
</test>
==========================
the Active Sheet which validates the datas with the schema :
============================== active-sheet.xcl
<?xml version="1.0" encoding="iso-8859-1"?>
<xcl:active-sheet
xmlns:xcl="
http://www.inria.fr/xml/active-tags/xcl"
xmlns:asl="
http://www.inria.fr/xml/active-schema"
<xcl
arse name="datas" source="datas.xml"/>
<asl
arse-schema name="schema" source="schema.asl"/>
<asl:validate schema="{ $schema }" node="{ $datas }" augment="yes"
deep="yes" report="report"/>
<xcl:for-each name="err" select="{ $report/* }">
<xcl:echo value="Error { name( value( $err/@reason-id ) ) }"/>
<xcl:echo value=" node : { value( $err/@path/@path ) }"/>
<xcl:echo value=" rule : { value(
$err/@rule-path/@rule-path ) }"/>
</xcl:for-each>
</xcl:active-sheet>
=====================
you see unusual XPath expressions above, because Active Tags allow to
use XPath on non-XML object, which is the case of "$err" : an object can
expose some properties as attributes, which value can be an object can
expose some properties as attributes, which explain why $err/@path/@path
is relevant
the output :
=====================
Error asl:elementExpected
node : {/test/table[3]/column[2]/}
rule :
{/asl:active-schema/asl:element[3]/asl:sequence/xcl:if/xcl:then/asl:element}
Error asl:noMoreContentAllowed
node : {/test/table[4]/column[3]/cell[3]}
rule : {/asl:active-schema/asl:element[3]}
Error asl:elementExpected
node : {/test/table[4]/column[4]/}
rule :
{/asl:active-schema/asl:element[3]/asl:sequence/xcl:if/xcl:then/asl:element}
Error asl:elementExpected
node : {/test/table[5]/cell[1]}
rule : {/asl:active-schema/asl:element[2]/asl:sequence/asl:element}
Error asl:noMoreContentAllowed
node : {/test/table[5]/cell[1]}
rule : {/asl:active-schema/asl:element[2]}
Error asl:noMoreContentAllowed
node : {/test/table[5]/cell[2]}
rule : {/asl:active-schema/asl:element[2]}
======================
the detailed specification :
http://disc.inria.fr/perso/philippe.poulard/xml/active-tags/active-schema/active-schema.html
the tool that implement all that stuff :
http://reflex.gforge.inria.fr/
you can download RefleX freely and run the given Active Sheet to check
the XML datas with the Active Schema
--
Cordialement,
///
(. .)
--------ooO--(_)--Ooo--------
| Philippe Poulard |