[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [Elist Home]
Subject: What exactly is prohibited by the constraint of RELAX NG?
Of three decision made today (att/elem in att, att/elem in list, duplicate attribute), the "duplicate attribute" looks like the most complex one. So here is my attempt to summarize it: restrictions: #1 For every group <group> p1 p2 </group> and <interleave> p1 p2 </interleave>, it is an error that p1 and p2 contains attribute patterns whose name may collide. #2 For every <oneOrMore> p1 </oneOrMore>, if p1 contains attribute patterns, then no <group/> or <interleave/> is allowed between that attribute and <oneOrMore/> Both restrictions apply after the normalization. This algorithm detects the first condition: NameClass possibleNames( Pattern p ) { switch( p ) { case <group> p1 p2 </group>: case <interleave> p1 p2 </interleave>: nc1 = possibleNames(p1) nc2 = possibleNames(p2) if( intersection of nc1 and nc2 is non-empty ) reject this pattern. return <choice> nc1 nc2 </choice>; case <choice> p1 p2 </choice>: return <choice> possibleNames(p1) possibleNames(p2) </choice>; case <attribute> nc p </attribute>: return nc; case <oneOrMore> p </oneOrMore>: return possibleNames(p); case <element> nc p </element>: case <empty/>: case <notAllowed/>: case <data/>: case <value/>: return <not><anyName/></not>; } This algorithm detects the 2nd condition by invoking "check(p,false)" void check( Pattern p ) { switch( p ) { case <group> p1 p2 </group>: case <interleave> p1 p2 </interleave>: case <choice> p1 p2 </choice>: check(p1,inOneOrMore); check(p2,inOneOrMore); case <oneOrMore> p </oneOrMore>: if(haveGroupedAttribute(p)) reject this pattern; case <attribute> nc p </attribute>: case <element> nc p </element>: case <empty/>: case <notAllowed/>: case <data/>: case <value/>: return; } boolean haveGroupedAttribute( Pattern p ) { switch( p ) { case <group> p1 p2 </group>: case <interleave> p1 p2 </interleave>: return haveAttribute(p1)||haveAttribute(p2); case <choice> p1 p2 </choice>: return haveGroupedAttribute(p1)||haveGroupedAttribute(p2); case <oneOrMore> p </oneOrMore>: return haveGroupedAttribute(p); case <attribute> nc p </attribute>: case <element> nc p </element>: case <empty/>: case <notAllowed/>: case <data/>: case <value/>: return false; } boolean haveAttribute( Pattern p ) { switch( p ) { case <group> p1 p2 </group>: case <interleave> p1 p2 </interleave>: case <choice> p1 p2 </choice>: return haveAttribute(p1)||haveAttribute(p2); case <oneOrMore> p </oneOrMore>: return haveAttribute(p); case <attribute> nc p </attribute>: return true; case <element> nc p </element>: case <empty/>: case <notAllowed/>: case <data/>: case <value/>: return false; } -- 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