{
System.out.println("================");
System.out.println("loadSteps for: "+compiler.getPatternString());
}
int stepType;
StepPattern step = null;
StepPattern firstStep = null, prevStep = null;
int analysis = analyze(compiler, stepOpCodePos, stepIndex);
while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
{
step = createDefaultStepPattern(compiler, stepOpCodePos, mpi, analysis,
firstStep, prevStep);
if (null == firstStep)
{
firstStep = step;
}
else
{
//prevStep.setNextWalker(step);
step.setRelativePathPattern(prevStep);
}
prevStep = step;
stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
if (stepOpCodePos < 0)
break;
}
int axis = Axis.SELF;
int paxis = Axis.SELF;
StepPattern tail = step;
for (StepPattern pat = step; null != pat;
pat = pat.getRelativePathPattern())
{
int nextAxis = pat.getAxis();
//int nextPaxis = pat.getPredicateAxis();
pat.setAxis(axis);
// The predicate axis can't be moved!!! Test Axes103
// pat.setPredicateAxis(paxis);
// If we have an attribute or namespace axis that went up, then
// it won't find the attribute in the inverse, since the select-to-match
// axes are not invertable (an element is a parent of an attribute, but
// and attribute is not a child of an element).
// If we don't do the magic below, then "@*/ancestor-or-self::*" gets
// inverted for match to "self::*/descendant-or-self::@*/parent::node()",
// which obviously won't work.
// So we will rewrite this as:
// "self::*/descendant-or-self::*/attribute::*/parent::node()"
// Child has to be rewritten a little differently:
// select: "@*/parent::*"
// inverted match: "self::*/child::@*/parent::node()"
// rewrite: "self::*/attribute::*/parent::node()"
// Axes that go down in the select, do not have to have special treatment
// in the rewrite. The following inverted match will still not select
// anything.
// select: "@*/child::*"
// inverted match: "self::*/parent::@*/parent::node()"
// Lovely business, this.
// -sb
int whatToShow = pat.getWhatToShow();
if(whatToShow == DTMFilter.SHOW_ATTRIBUTE ||
whatToShow == DTMFilter.SHOW_NAMESPACE)
{
int newAxis = (whatToShow == DTMFilter.SHOW_ATTRIBUTE) ?
Axis.ATTRIBUTE : Axis.NAMESPACE;
if(isDownwardAxisOfMany(axis))
{
StepPattern attrPat = new StepPattern(whatToShow,
pat.getNamespace(),
pat.getLocalName(),
//newAxis, pat.getPredicateAxis);
newAxis, 0); // don't care about the predicate axis
XNumber score = pat.getStaticScore();
pat.setNamespace(null);
pat.setLocalName(NodeTest.WILD);
attrPat.setPredicates(pat.getPredicates());
pat.setPredicates(null);
pat.setWhatToShow(DTMFilter.SHOW_ELEMENT);
StepPattern rel = pat.getRelativePathPattern();
pat.setRelativePathPattern(attrPat);
attrPat.setRelativePathPattern(rel);
attrPat.setStaticScore(score);
// This is needed to inverse a following pattern, because of the
// wacky Xalan rules for following from an attribute. See axes108.
// By these rules, following from an attribute is not strictly
// inverseable.
if(Axis.PRECEDING == pat.getAxis())
pat.setAxis(Axis.PRECEDINGANDANCESTOR);
else if(Axis.DESCENDANT == pat.getAxis())
pat.setAxis(Axis.DESCENDANTORSELF);
pat = attrPat;
}
else if(Axis.CHILD == pat.getAxis())
{
// In this case just change the axis.
// pat.setWhatToShow(whatToShow);
pat.setAxis(Axis.ATTRIBUTE);
}
}
axis = nextAxis;
//paxis = nextPaxis;
tail = pat;
}
if(axis < Axis.ALL)
{
StepPattern selfPattern = new ContextMatchStepPattern(axis, paxis);
// We need to keep the new nodetest from affecting the score...
XNumber score = tail.getStaticScore();
tail.setRelativePathPattern(selfPattern);
tail.setStaticScore(score);
selfPattern.setStaticScore(score);
}
if (DEBUG_PATTERN_CREATION)
{
System.out.println("Done loading steps: "+step.toString());