You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Gary L Peskin <ga...@firstech.com> on 2000/10/08 10:44:17 UTC

XalanJ2 XRTreeFrag nodelist()

While trying to implement the nodeset extension into XalanJ2, I came
across a curious thing.

The following stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl
="http://www.w3.org/1999/XSL/Transform">
  <xsl:variable name="greeting">abc<h1>Hello,
World!</h1>def</xsl:variable>
    <xsl:template match="/">
      <myoutput>
        1: <xsl:for-each select="$greeting">*<xsl:copy-of
select="."/>*</xsl:for-each>
      </myoutput>
  </xsl:template>
</xsl:stylesheet>

produces a ClassCastException in
org.apache.xalan.transformer.TransformerImpl.transformSelectedNodes() at
line 1104:

  xctxt.pushContextNodeList((ContextNodeList) sourceNodes)

sourceNodes is declared as a NodeIterator and, in this case, obviously
cannot be cast to a ContextNodeList.  sourceNodes is, in turn, obtained
from

  sourceNodes = result.nodeset()

at line 1049.  In this case, result is a result tree fragment
represented by $greeting.  The nodeset() method returns an inner class
object NodeIteratorWrapper which does not implement the ContextNodeList
interface and this is why the cast fails.

To my way of thinking, to implement XSLT 1.0, this for-each element
should fail with an error message indicating that the RTF cannot be
converted to a nodeset.  Indeed, this is what happens in XalanJ1.  I
think that implementing any other behavior in advance of another spec
anticipating the elimination of RTFs is premature.  Nevertheless, it
seems like this is either a work in progress or a bug.

If this is going to be implemented in XalanJ2, it needs to be fixed and
then we won't need the nodeset extension.  If this is not going to be
implemented in XalanJ2, then I'll continue work on the nodeset
extension.

If we're going to stick with the XSLT 1.0 spec in XalanJ2, then we need
to decide what to convert an RTF to when passing it to a java
extension.  This is handled in MethodResolver.convert() which currently
attempts to convert the RTF to a NodeIterator if the target java type is
either a NodeIterator or an Object.  I have no problem with converting
to a NodeIterator (but _not_ by calling nodeset()!) but it seems to me
that if the java type is an Object, we should just pass the RTF in as
DocumentFragment.

Your thoughts??

Also, a System.out.println call has been left in XRTreeFrag.nodeset().

Gary