[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