Uploaded image for project: 'XalanC'
  1. XalanC
  2. XALANC-540

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

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: CurrentCVS, 1.8, 1.9
    • Fix Version/s: CurrentCVS
    • Component/s: XPathC
    • Labels:
      None
    • Environment:
      Win2k on ix86.

      Description

      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(//*)"/><Unable to render embedded object: File (-- Does not work) not found. -->
      <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.

        Attachments

        1. patch.txt
          2 kB
          David N Bertoni

          Activity

            People

            • Assignee:
              dbertoni David N Bertoni
              Reporter:
              aleguenn@free.fr Alain Le Guennec
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: