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; } }
/** * 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("&", "&") + "\""; 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); } }