[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