/**
   * Get the XObject representation of the variable.
   *
   * @param transformer non-null reference to the the current transform-time state.
   * @param sourceNode non-null reference to the <a
   *     href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
   * @return the XObject representation of the variable.
   * @throws javax.xml.transform.TransformerException
   */
  public XObject getValue(TransformerImpl transformer, int sourceNode) throws TransformerException {

    XObject var;
    XPathContext xctxt = transformer.getXPathContext();

    xctxt.pushCurrentNode(sourceNode);

    try {
      if (null != m_selectPattern) {
        var = m_selectPattern.execute(xctxt, sourceNode, this);

        var.allowDetachToRelease(false);

        if (transformer.getDebug())
          transformer
              .getTraceManager()
              .fireSelectedEvent(sourceNode, this, "select", m_selectPattern, var);
      } else if (null == getFirstChildElem()) {
        var = XString.EMPTYSTRING;
      } else {

        // Use result tree fragment.
        // Global variables may be deferred (see XUnresolvedVariable) and hence
        // need to be assigned to a different set of DTMs than local variables
        // so they aren't popped off the stack on return from a template.
        int df;

        // Bugzilla 7118: A variable set via an RTF may create local
        // variables during that computation. To keep them from overwriting
        // variables at this level, push a new variable stack.
        ////// PROBLEM: This is provoking a variable-used-before-set
        ////// problem in parameters. Needs more study.
        try {
          ////////// xctxt.getVarStack().link(0);
          if (m_parentNode instanceof Stylesheet) // Global variable
          df = transformer.transformToGlobalRTF(this);
          else df = transformer.transformToRTF(this);
        } finally {
          ////////////// xctxt.getVarStack().unlink();
        }

        var = new XRTreeFrag(df, xctxt, this);
      }
    } finally {
      xctxt.popCurrentNode();
    }

    return var;
  }
예제 #2
0
  /**
   * Evaluate XPath string to an XObject. XPath namespace prefixes are resolved from the
   * namespaceNode. The implementation of this is a little slow, since it creates a number of
   * objects each time it is called. This could be optimized to keep the same objects around, but
   * then thread-safety issues would arise.
   *
   * @param contextNode The node to start searching from.
   * @param xpathnode
   * @param str
   * @param prefixResolver Will be called if the parser encounters namespace prefixes, to resolve
   *     the prefixes to URLs.
   * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never
   *     be null.
   * @see org.apache.xpath.objects.XObject
   * @see org.apache.xpath.objects.XNull
   * @see org.apache.xpath.objects.XBoolean
   * @see org.apache.xpath.objects.XNumber
   * @see org.apache.xpath.objects.XString
   * @see org.apache.xpath.objects.XRTreeFrag
   * @throws TransformerException
   */
  public XObject eval(Node contextNode, Node xpathnode, String str, PrefixResolver prefixResolver)
      throws TransformerException {

    // Since we don't have a XML Parser involved here, install some default support
    // for things like namespaces, etc.
    // (Changed from: XPathContext xpathSupport = new XPathContext();
    //    because XPathContext is weak in a number of areas... perhaps
    //    XPathContext should be done away with.)
    // Create the XPath object.
    // String str = CachedXPathFuncHereAPI.getStrFromNode(xpathnode);
    // only check if string points to different object (for performance)
    if (str != xpathStr) {
      if (str.indexOf("here()") > 0) {
        _context.reset();
        _dtmManager = _context.getDTMManager();
      }
      try {
        xpath = createXPath(str, prefixResolver);
      } catch (TransformerException ex) {
        // Try to see if it is a problem with the classloader.
        Throwable th = ex.getCause();
        if (th instanceof ClassNotFoundException) {
          if (th.getMessage().indexOf("FuncHere") > 0) {
            throw new RuntimeException(I18n.translate("endorsed.jdk1.4.0") /*,*/ + ex);
          }
        }
        throw ex;
      }
      xpathStr = str;
    }

    // Execute the XPath, and have it return the result
    if (this._funcHereContext == null) {
      this._funcHereContext = new FuncHereContext(xpathnode, this._dtmManager);
    }

    int ctxtNode = this._funcHereContext.getDTMHandleFromNode(contextNode);

    return xpath.execute(this._funcHereContext, ctxtNode, prefixResolver);
  }
예제 #3
0
  /**
   * Evaluate XPath string to an XObject. XPath namespace prefixes are resolved from the
   * namespaceNode. The implementation of this is a little slow, since it creates a number of
   * objects each time it is called. This could be optimized to keep the same objects around, but
   * then thread-safety issues would arise.
   *
   * @param contextNode The node to start searching from.
   * @param xpathnode
   * @param str
   * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
   * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never
   *     be null.
   * @see org.apache.xpath.objects.XObject
   * @see org.apache.xpath.objects.XNull
   * @see org.apache.xpath.objects.XBoolean
   * @see org.apache.xpath.objects.XNumber
   * @see org.apache.xpath.objects.XString
   * @see org.apache.xpath.objects.XRTreeFrag
   * @throws TransformerException
   */
  public XObject eval(Node contextNode, Node xpathnode, String str, Node namespaceNode)
      throws TransformerException {
    //  Create the XPath object.
    // String str = CachedXPathFuncHereAPI.getStrFromNode(xpathnode);

    // Since we don't have a XML Parser involved here, install some default support
    // for things like namespaces, etc.
    // (Changed from: XPathContext xpathSupport = new XPathContext();
    //    because XPathContext is weak in a number of areas... perhaps
    //    XPathContext should be done away with.)
    if (this._funcHereContext == null) {
      this._funcHereContext = new FuncHereContext(xpathnode, this._dtmManager);
    }

    // Create an object to resolve namespace prefixes.
    // XPath namespaces are resolved from the input context node's document element
    // if it is a root node, or else the current context node (for lack of a better
    // resolution space, given the simplicity of this sample code).
    PrefixResolverDefault prefixResolver =
        new PrefixResolverDefault(
            (namespaceNode.getNodeType() == Node.DOCUMENT_NODE)
                ? ((Document) namespaceNode).getDocumentElement()
                : namespaceNode);

    // only check if string points to different object (for performance)
    if (str != xpathStr) {
      if (str.indexOf("here()") > 0) {
        _context.reset();
        _dtmManager = _context.getDTMManager();
      }
      xpath = createXPath(str, prefixResolver);
      xpathStr = str;
    }

    // Execute the XPath, and have it return the result
    // return xpath.execute(xpathSupport, contextNode, prefixResolver);
    int ctxtNode = this._funcHereContext.getDTMHandleFromNode(contextNode);

    return xpath.execute(this._funcHereContext, ctxtNode, prefixResolver);
  }