XPath absolute location path does not work when the context node was obtained 
from a result tree fragment through exsl:node-set()
---------------------------------------------------------------------------------------------------------------------------------

         Key: XALANC-540
         URL: http://issues.apache.org/jira/browse/XALANC-540
     Project: XalanC
        Type: Bug
  Components: XPathC  
    Versions: CurrentCVS, 1.8, 1.9    
 Environment: Win2k on ix86.
    Reporter: Alain Le Guennec


XPath absolute location path does not work when the context node was obtained 
from a result tree fragment through exsl:node-set().
Consider the following stylesheet (applied to any input document, the actual 
input does not matter):

<?xml version="1.0"  encoding = "ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns:exsl="http://exslt.org/common";>
        <xsl:template match="/">
                <xsl:variable name="var-rtf">
                        <foo>
                                <bar/>
                        </foo>
                </xsl:variable>
                <xsl:variable name="var" select="exsl:node-set($var-rtf)/*"/>
                <xsl:apply-templates select="$var">
                        <xsl:with-param name="root" select="$var"/>
                </xsl:apply-templates>
        </xsl:template>

        <xsl:template match="foo">
                <xsl:param name="root"/>
                <!-- Here the context node belongs to the tree fragment -->
                <xsl:variable name="count-from-implicit-root" 
select="count(//*)"/><!-- Does not work! -->
                <xsl:variable name="count-from-explicit-root" 
select="count($root/descendant-or-self::node())"/><!-- OK -->
                <xsl:choose>
                        <xsl:when test="$count-from-implicit-root = 
$count-from-explicit-root">
                                <xsl:message>No bug: There are <xsl:value-of 
select="$count-from-implicit-root"/> elements in the tree 
fragment.</xsl:message>
                        </xsl:when>
                        <xsl:otherwise>
                                <!-- Navigation from the root of the tree 
fragment does not work. -->
                                <xsl:message>Bug: There should be <xsl:value-of 
select="$count-from-explicit-root"/> elements in the tree fragment, not 
<xsl:value-of select="$count-from-implicit-root"/>.</xsl:message>
                        </xsl:otherwise>
                </xsl:choose>
        </xsl:template>
</xsl:stylesheet>

Executing this stylesheet prints
    "Bug: There should be 2 elements in the tree fragment, not 0."
where as it should print
    "No bug: There are 2 elements in the tree fragment."

Apparently, the error lies in XPath.cpp, in function XPath::findRoot().
I think it's because the XalanNodes representing the elements are connected
to the XalanSourceTreeDocumentFragment, not to its owning 
XalanSourceTreeDocument.
In this particular case, the actual root is not a DOCUMENT_NODE, but a 
DOCUMENT_FRAGMENT_NODE.
Here is modified version of findRoot() that apparently fixes the problem (old 
code kept as comment):

XPath::OpCodeMapPositionType
XPath::findRoot(
                        XPathExecutionContext&  /* executionContext */,
                        XalanNode*                              context, 
                        OpCodeMapPositionType   opPos,
                        OpCodeMapValueType              /* stepType */,
                        MutableNodeRefList&     subQueryResults) const
{
        assert(subQueryResults.empty() == true);

        const XPathExpression&  currentExpression = getExpression();

        const OpCodeMapValueType    argLen =
                currentExpression.getOpCodeArgumentLength(opPos);

//      XalanNode* const        docContext = XalanNode::DOCUMENT_NODE == 
context->getNodeType() ?
//                                                                      context 
:
//                                                                      
context->getOwnerDocument();
        XalanNode* docContext = context;
        while (docContext->getNodeType() != XalanNode::DOCUMENT_NODE && 
docContext->getNodeType() != XalanNode::DOCUMENT_FRAGMENT_NODE) {
                docContext = DOMServices::getParentOfNode(*docContext);
        }
        assert(docContext != 0);

        subQueryResults.addNode(docContext);

        subQueryResults.setDocumentOrder();

        return opPos + argLen + 3;
}

Hope this helps.
Regards,
Alain Le Guennec.


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to