[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [Elist Home]
Subject: Re: [relax-ng] Re: RELAX NG + Schematron
> If you're implementing on top of SAX, that's true. But since RELAX NG does
> not alter the infoset, I don't think there is any conceptual incoherence in
> having the assertion affect the match, and I don't think it would be hard to
> do this on top of the DOM.
Of course you are right. I'm sometimes surprised at how foolish I can
be.
> For the other approach, it would make more sense to simply have an attribute
> with an XPath expression:
>
> <element name="orders" x:require="count(order) > 4">
> <oneOrMore>
> <ref name="order"/>
> </oneOrMore>
> </element>
I don't think the syntax of writing assertions has something to do
with the algorithm. This way of writing assertions can work fine with
the "RNG-first-n-Schematron-later" style, and writing <s:rule> and
<s:assertion> can work well with the "use-schematron-to-guide-RNG"
style, too.
> By sound you mean if the restriction holds, then type-assignment is possible
> (or easy for some definition of easy)? By complete, if type-assignment is
> possible, then the restriction must hold? Right?
Yes.
> I would be inclined to use the same approach that we had with xsl:key and
> xsl:keyRef, namely that there is no path wrt respect to which two different
> sets of s:assert elements are applicable.
Yeah, I didn't realize that we can use the same algorithm as
key/keyref.
I was thinking about a bit more relaxed (but time-consuming) algorithm.
By replacing all <attribute>,<value>,<data> and <list> with <empty/>,
one can get element-only pattern P.
Then:
function check( Pattern p ) {
if( p is already checked ) return;
for( each e in first(p) ) {
E' := { e' | e' \in first(p) and e ~ e' }
if( E' contains more than one element with assertion )
eureka!;
check( choice of all content models in E' );
check( residual of p by E' );
}
}
By using
e ~ e' iff the intersection of their name classes is non-empty.
and
function first( Pattern p ) {
switch(p) {
case <group> p1 p2 </group>
if(!p1.isNullable) return first(p1);
else return union(first(p1),first(p2));
case <interleave> p1 p2 </interleave>:
case <choice> p1 p2 </choice>:
return union(first(p1),first(p2));
case <element>:
return { p };
}
}
This algorithm is better in the sense that it allows more patterns,
but harder and time-consuming to check.
regards,
--
Kohsuke KAWAGUCHI +1 650 786 0721
Sun Microsystems kohsuke.kawaguchi@sun.com
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [Elist Home]
Powered by eList eXpress LLC