public static String getType(Expression expr, XPathContext context) throws XPathException {
   ValueRepresentation vr = ExpressionTool.lazyEvaluate(expr, context, 1);
   ItemType it = Value.asValue(vr).getItemType(context.getConfiguration().getTypeHierarchy());
   if (it instanceof SchemaType) {
     return "xs:" + ((SchemaType) it).getName();
   }
   return "xs:any";
 }
 /**
  * Get the value converted to a double using the XPath casting rules
  *
  * @return the result of converting to a double
  * @throws SaxonApiException if the value cannot be cast to a double
  */
 public double getDoubleValue() throws SaxonApiException {
   AtomicValue av = (AtomicValue) getUnderlyingValue();
   if (av instanceof BooleanValue) {
     return ((BooleanValue) av).getBooleanValue() ? 0.0 : 1.0;
   } else if (av instanceof NumericValue) {
     return ((NumericValue) av).getDoubleValue();
   } else if (av instanceof StringValue) {
     return Value.stringToNumber(av.getStringValueCS());
   } else {
     throw new SaxonApiException("Cannot cast item to a double");
   }
 }
 /**
  * Get the value converted to an integer using the XPath casting rules
  *
  * @return the result of converting to an integer
  * @throws SaxonApiException if the value cannot be cast to an integer
  */
 public long getLongValue() throws SaxonApiException {
   AtomicValue av = (AtomicValue) getUnderlyingValue();
   if (av instanceof BooleanValue) {
     return ((BooleanValue) av).getBooleanValue() ? 0L : 1L;
   } else if (av instanceof NumericValue) {
     try {
       return ((NumericValue) av).longValue();
     } catch (XPathException e) {
       throw new SaxonApiException("Cannot cast item to an integer");
     }
   } else if (av instanceof StringValue) {
     return (long) Value.stringToNumber(av.getStringValueCS());
   } else {
     throw new SaxonApiException("Cannot cast item to an integer");
   }
 }
 /**
  * Perform optimisation of an expression and its subexpressions.
  *
  * <p>
  *
  * <p>This method is called after all references to functions and variables have been resolved to
  * the declaration of the function or variable, and after all type checking has been done.
  *
  * @param visitor an expression visitor
  * @param contextItemType the static type of "." at the point where this expression is invoked.
  *     The parameter is set to null if it is known statically that the context item will be
  *     undefined. If the type of the context item is not known statically, the argument is set to
  *     {@link net.sf.saxon.type.Type#ITEM_TYPE}
  * @return the original expression, rewritten if appropriate to optimize execution
  * @throws XPathException if an error is discovered during this phase (typically a type error)
  */
 public Expression optimize(ExpressionVisitor visitor, ItemType contextItemType)
     throws XPathException {
   operand0 = visitor.optimize(operand0, contextItemType);
   operand1 = visitor.optimize(operand1, contextItemType);
   // if both operands are known, pre-evaluate the expression
   try {
     if ((operand0 instanceof Literal) && (operand1 instanceof Literal)) {
       Value v =
           Value.asValue(evaluateItem(visitor.getStaticContext().makeEarlyEvaluationContext()));
       return Literal.makeLiteral(v);
     }
   } catch (XPathException err) {
     // if early evaluation fails, suppress the error: the value might
     // not be needed at run-time
   }
   return this;
 }
  /**
   * Convert an XPath value to an object in this object model. If the supplied value can be
   * converted to an object in this model, of the specified class, then the conversion should be
   * done and the resulting object returned. If the value cannot be converted, the method should
   * return null. Note that the supplied class might be a List, in which case the method should
   * inspect the contents of the Value to see whether they belong to this object model.
   *
   * @throws XPathException if the target class is explicitly associated with this object model, but
   *     the supplied value cannot be converted to the appropriate class
   */
  public Object convertXPathValueToObject(Value value, Class target, XPathContext context)
      throws XPathException {
    // We accept the object if (a) the target class is Node, Node[], or NodeList,
    // or (b) the supplied object is a node, or sequence of nodes, that wrap DOM nodes,
    // provided that the target class is Object or a collection class
    boolean requireDOM =
        (Node.class.isAssignableFrom(target)
            || (target == NodeList.class)
            || (target.isArray() && Node.class.isAssignableFrom(target.getComponentType())));

    // Note: we allow the declared type of the method argument to be a subclass of Node. If the
    // actual
    // node supplied is the wrong kind of node, this will result in a Java exception.

    boolean allowDOM =
        (target == Object.class
            || target.isAssignableFrom(ArrayList.class)
            || target.isAssignableFrom(HashSet.class)
            || (target.isArray() && target.getComponentType() == Object.class));
    if (!(requireDOM || allowDOM)) {
      return null;
    }
    List nodes = new ArrayList(20);

    SequenceIterator iter = value.iterate(context);
    while (true) {
      Item item = iter.next();
      if (item == null) {
        break;
      }
      if (item instanceof VirtualNode) {
        Object o = ((VirtualNode) item).getUnderlyingNode();
        if (o instanceof Node) {
          nodes.add(o);
        } else {
          if (requireDOM) {
            DynamicError err =
                new DynamicError(
                    "Extension function required class "
                        + target.getName()
                        + "; supplied value of class "
                        + item.getClass().getName()
                        + " could not be converted");
            throw err;
          }
          ;
        }
      } else if (requireDOM) {
        if (item instanceof NodeInfo) {
          nodes.add(NodeOverNodeInfo.wrap((NodeInfo) item));
        } else {
          DynamicError err =
              new DynamicError(
                  "Extension function required class "
                      + target.getName()
                      + "; supplied value of class "
                      + item.getClass().getName()
                      + " could not be converted");
          throw err;
        }
      } else {
        return null; // DOM Nodes are not actually required; let someone else try the conversion
      }
    }

    if (nodes.size() == 0 && !requireDOM) {
      return null; // empty sequence supplied - try a different mapping
    }
    if (Node.class.isAssignableFrom(target)) {
      if (nodes.size() != 1) {
        DynamicError err =
            new DynamicError(
                "Extension function requires a single DOM Node"
                    + "; supplied value contains "
                    + nodes.size()
                    + " nodes");
        throw err;
      }
      return nodes.get(0);
      // could fail if the node is of the wrong kind
    } else if (target == NodeList.class) {
      return new DOMNodeList(nodes);
    } else if (target.isArray() && target.getComponentType() == Node.class) {
      Node[] array = new Node[nodes.size()];
      nodes.toArray(array);
      return array;
    } else if (target.isAssignableFrom(ArrayList.class)) {
      return nodes;
    } else if (target.isAssignableFrom(HashSet.class)) {
      return new HashSet(nodes);
    } else {
      // after all this work, give up
      return null;
    }
  }
示例#6
0
 /**
  * Evaluate the expression
  *
  * @param arguments the values of the arguments, supplied as SequenceIterators
  * @param context the dynamic evaluation context
  * @return the result of the evaluation, in the form of a SequenceIterator
  * @throws net.sf.saxon.trans.XPathException if a dynamic error occurs during the evaluation of
  *     the expression
  */
 public SequenceIterator call(SequenceIterator[] arguments, XPathContext context)
     throws XPathException {
   StringValue hrefVal = (StringValue) arguments[0].next();
   String encoding = (getNumberOfArguments() == 2 ? arguments[1].next().getStringValue() : null);
   return Value.asIterator(evalUnparsedText(hrefVal, encoding, context));
 }
  public SequenceIterator iterate(XPathContext context) throws XPathException {
    Controller controller = context.getController();
    ObjectValue ov = (ObjectValue) controller.getParameter("{" + Test.TE_NS + "}core");
    TECore core = (TECore) ov.getObject();

    Expression[] argExpressions = getArguments();
    String xml = "<params>\n";
    List<QName> params = fe.getParams();
    for (int i = 0; i < params.size(); i++) {
      QName param = params.get(i);
      xml += "<param";
      xml += " local-name=\"" + param.getLocalPart() + "\"";
      xml += " namespace-uri=\"" + param.getNamespaceURI() + "\"";
      xml += " prefix=\"" + param.getPrefix() + "\"";
      ValueRepresentation vr = ExpressionTool.eagerEvaluate(argExpressions[i], context);
      // ValueRepresentation vr =
      // ExpressionTool.lazyEvaluate(argExpressions[i], context, 1);
      Value v = Value.asValue(vr);
      try {
        Node n = (Node) v.convertToJava(Node.class, context);
        int type = n.getNodeType();
        if (type == Node.ATTRIBUTE_NODE) {
          xml += ">\n";
          Attr attr = (Attr) n;
          xml +=
              "<value " + attr.getNodeName() + "=\"" + attr.getValue().replace("&", "&amp;") + "\"";
          if (attr.getPrefix() != null) {
            xml += " xmlns:" + attr.getPrefix() + "=\"" + attr.getNamespaceURI() + "\"";
          }
          xml += "/>\n";
          // } else if (type == Node.ELEMENT_NODE || type ==
          // Node.DOCUMENT_NODE) {
          // xml += ">\n";
          // xml += "<value>";
          // xml += DomUtils.serializeNode(n);
          // xml += "</value>\n";
        } else if (type == Node.ELEMENT_NODE) {
          xml += " type=\"node()\">\n";
          xml += "<value>";
          xml += DomUtils.serializeNode(n);
          xml += "</value>\n";
        } else if (type == Node.DOCUMENT_NODE) {
          xml += " type=\"document-node()\">\n";
          xml += "<value>";
          xml += DomUtils.serializeNode(n);
          xml += "</value>\n";
        } else {
          ItemType it = v.getItemType(context.getConfiguration().getTypeHierarchy());
          xml += " type=\"" + getTypeName(it) + "\">\n";
          xml += "<value>" + n.getNodeValue() + "</value>\n";
        }
      } catch (Exception e) {
        ItemType it = v.getItemType(context.getConfiguration().getTypeHierarchy());
        xml += " type=\"" + getTypeName(it) + "\">\n";
        xml += "<value>" + v.getStringValue() + "</value>\n";
      }
      xml += "</param>\n";
    }
    xml += "</params>";
    // System.out.println(xml);
    Source src = new StreamSource(new CharArrayReader(xml.toCharArray()));
    // XdmValue result = null;
    NodeInfo result = null;
    try {
      // result = core.executeTemplate(fe, Globals.builder.build(src),
      // context);
      NodeInfo paramsNode = core.getEngine().getBuilder().build(src).getUnderlyingNode();
      result = core.executeXSLFunction(context, fe, paramsNode);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    if (result == null) {
      return EmptyIterator.getInstance();
    } else {
      // Value v = Value.asValue(result);
      // return v.iterate();
      return result.iterateAxis(Axis.CHILD);
    }
  }