I see I wasn't clear on what the actual problem was and I apologize. Let
me try again.

I'm trying to mimic the behavior of XSLT's for-each instruction:

  <xsl:for-each select="[xp1]">
    <xsl:value-of select="[xp2]" />
  </xsl:for-each>

The exact expressions are not relevant here. The programming solution in
Xalan-J should work for *any* XPath expressions xp1 and xp2. The
expression xp2="position()" was chosen because it requires current node
list in its evaluation context. What I'm trying to do is to execute an
XPath expression not only in the context of the current node, but also
in the context of *current node list*, as XSLT 1.0 specifies:

"When a template is instantiated, it is always instantiated with respect
to a current node and a current node list. The current node is always a
member of the current node list. Many operations in XSLT are relative to
the current node. Only a few instructions change the current node list
or the current node (see [5 Template Rules] and [8 Repetition]); during
the instantiation of one of these instructions, the current node list
changes to a new list of nodes and each member of this new list becomes
the current node in turn; after the instantiation of the instruction is
complete, the current node and current node list revert to what they
were before the instruction was instantiated."

Note that [8 Repetition] refers to <for-each>.

XPath 1.0 specifies:

"Expression evaluation occurs with respect to a context... The context
consists of:

 * a node (the context node)
 * a pair of non-zero positive integers (the context position and the
   context size)..."

This is provided for in XSLT:

"In XSLT, an outermost expression (i.e. an expression that is not part
of another expression) gets its context as follows:

  * the context node comes from the current node
  * the context position comes from the position of the current node in
    the current node list; the first position is 1
  * the context size comes from the size of the current node list..."

So to reformulate the question in terms of XPath spec:

  How can I execute an arbitrary XPath expression in Xalan-J XPath API
  with respect to not only a context node, but also a context position
  and a context size?

I.e. an equivalent of:

test( Document doc, String es1, String es2 )
{
  XPathContext context = new XPathContext();
  XPath xp1 = new XPath( es1, null, null, XPath.SELECT );
  XPath xp2 = new XPath( es2, null, null, XPath.SELECT );
  XObject xo1 = xp1.execute( context, doc, null );
  NodeList nodelist = xo1.nodelist();
  int contextSize = nodelist.getLength();
  context.setContextSize( contextSize );
  for ( int i = 0; i < contextSize; i ++ )
  {
    Node n = nodelist.item( i );
    context.setContextPosition( i + 1 );
    XObject xo2 = xp2.execute( context, n, null );
    System.out.print( xo2 );
  }
}

Of course, methods setContextPosition and setContextSize do not exist in
class XPathContext. Methods resembling setContextNodeList exist (e.g.
pushContextNodeList), but I can't figure out how to use them. I've tried
adapting code from org.apache.xalan.templates.ElemForEach but I got
really lost in complicated API.

Here's one observation which backs up my theory. If I use:

  context.pushContextNodeList( (DTMIterator) xo1 );

and e2="last()", test() prints out "333". So, the last() function works
as expected. However, position() always returns "0";



Reply via email to