/** * Process this instruction * * @param context the dynamic context of the transformation * @return a TailCall to be executed by the caller, always null for this instruction */ public TailCall processLeavingTail(XPathContext context) throws XPathException { Controller controller = context.getController(); SequenceReceiver out = context.getReceiver(); int opt = options; int ann = annotation; // we may need to change the namespace prefix if the one we chose is // already in use with a different namespace URI: this is done behind the scenes // by the Outputter CharSequence value = expandChildren(context); if (schemaType != null) { // test whether the value actually conforms to the given type XPathException err = schemaType.validateContent( value, DummyNamespaceResolver.getInstance(), context.getConfiguration().getNameChecker()); if (err != null) { ValidationException verr = new ValidationException( "Attribute value " + Err.wrap(value, Err.VALUE) + " does not the match the required type " + schemaType.getDescription() + ". " + err.getMessage()); verr.setErrorCode("XTTE1540"); verr.setLocator(this); throw verr; } } else if (validationAction == Validation.STRICT || validationAction == Validation.LAX) { try { ann = controller.getConfiguration().validateAttribute(nameCode, value, validationAction); } catch (ValidationException e) { DynamicError err = DynamicError.makeDynamicError(e); String errorCode = e.getErrorCodeLocalPart(); if (errorCode == null) { errorCode = (validationAction == Validation.STRICT ? "XTTE1510" : "XTTE1515"); } err.setErrorCode(errorCode); err.setXPathContext(context); err.setLocator(this); err.setIsTypeError(true); throw err; } } try { out.attribute(nameCode, ann, value, locationId, opt); } catch (XPathException err) { throw dynamicError(this, err, context); } return null; }
/** Evaluate in a context where a string is wanted */ public CharSequence evaluateAsString(XPathContext context) throws XPathException { int numArgs = argument.length; Controller ctrl = context.getController(); DecimalSymbols dfs = decimalFormatSymbols; AtomicValue av0 = (AtomicValue) argument[0].evaluateItem(context); if (av0 == null) { av0 = DoubleValue.NaN; } NumericValue number = (NumericValue) av0; if (dfs == null) { // the decimal-format name was not resolved statically if (requireFixup) { // we registered for a fixup, but none came dynamicError("Unknown decimal format name", "XTDE1280", context); return null; } DecimalFormatManager dfm = ctrl.getExecutable().getDecimalFormatManager(); if (numArgs == 2) { dfs = dfm.getDefaultDecimalFormat(); } else { // the decimal-format name was given as a run-time expression String lexicalName = argument[2].evaluateItem(context).getStringValue(); StructuredQName qName = null; try { qName = StructuredQName.fromLexicalQName( lexicalName, false, context.getConfiguration().getNameChecker(), nsContext); } catch (XPathException e) { dynamicError("Invalid decimal format name. " + e.getMessage(), "XTDE1280", context); } dfs = dfm.getNamedDecimalFormat(qName); if (dfs == null) { dynamicError( "format-number function: decimal-format '" + lexicalName + "' is not defined", "XTDE1280", context); return null; } } } SubPicture[] pics = subPictures; if (pics == null) { String format = argument[1].evaluateItem(context).getStringValue(); pics = getSubPictures(format, dfs); } return formatNumber(number, pics, dfs).toString(); }
public Item evaluateItem(XPathContext context) throws XPathException { Orphan o = (Orphan) super.evaluateItem(context); if (schemaType != null) { XPathException err = schemaType.validateContent( o.getStringValueCS(), DummyNamespaceResolver.getInstance(), context.getConfiguration().getNameChecker()); if (err != null) { throw new ValidationException( "Attribute value " + Err.wrap(o.getStringValueCS(), Err.VALUE) + " does not the match the required type " + schemaType.getDescription() + ". " + err.getMessage()); } o.setTypeAnnotation(schemaType.getFingerprint()); if (schemaType.isNamespaceSensitive()) { throw new DynamicError( "Cannot validate a parentless attribute whose content is namespace-sensitive"); } } else if (validationAction == Validation.STRICT || validationAction == Validation.LAX) { try { int ann = context .getController() .getConfiguration() .validateAttribute(nameCode, o.getStringValueCS(), validationAction); o.setTypeAnnotation(ann); } catch (ValidationException e) { DynamicError err = DynamicError.makeDynamicError(e); err.setErrorCode(e.getErrorCodeLocalPart()); err.setXPathContext(context); err.setLocator(this); err.setIsTypeError(true); throw err; } } return o; }
/** Evaluate as an expression. */ public Item evaluateItem(XPathContext context) throws XPathException { if (isLazyConstruction() && (context.getConfiguration().areAllNodesUntyped() || (validation == Validation.PRESERVE && getSchemaType() == null))) { return new UnconstructedDocument(this, context); } else { Controller controller = context.getController(); DocumentInfo root; if (textOnly) { CharSequence textValue; if (constantText != null) { textValue = constantText; } else { FastStringBuffer sb = new FastStringBuffer(100); SequenceIterator iter = content.iterate(context); while (true) { Item item = iter.next(); if (item == null) break; sb.append(item.getStringValueCS()); } textValue = sb.condense(); } root = new TextFragmentValue(textValue, getBaseURI()); ((TextFragmentValue) root).setConfiguration(controller.getConfiguration()); } else { try { XPathContext c2 = context.newMinorContext(); c2.setOrigin(this); Builder builder = controller.makeBuilder(); // builder.setSizeParameters(treeSizeParameters); builder.setLineNumbering(controller.getConfiguration().isLineNumbering()); // receiver.setSystemId(getBaseURI()); builder.setBaseURI(getBaseURI()); builder.setTiming(false); PipelineConfiguration pipe = controller.makePipelineConfiguration(); pipe.setHostLanguage(getHostLanguage()); // pipe.setBaseURI(baseURI); builder.setPipelineConfiguration(pipe); c2.changeOutputDestination( null, builder, false, getHostLanguage(), validation, getSchemaType()); Receiver out = c2.getReceiver(); out.open(); out.startDocument(0); content.process(c2); out.endDocument(); out.close(); root = (DocumentInfo) builder.getCurrentRoot(); } catch (XPathException e) { e.maybeSetLocation(this); e.maybeSetContext(context); throw e; } } return root; } }
/** Enumerate the results of the expression */ public SequenceIterator iterate(XPathContext context) throws XPathException { Controller controller = context.getController(); Item arg2; try { arg2 = argument[2].evaluateItem(context); } catch (XPathException e) { if ("XPDY0002".equals(e.getErrorCodeLocalPart())) { dynamicError( "Cannot call the key() function when there is no context item", "XTDE1270", context); return null; } else if ("XPDY0050".equals(e.getErrorCodeLocalPart())) { dynamicError( "In the key() function," + " the node supplied in the third argument (or the context node if absent)" + " must be in a tree whose root is a document node", "XTDE1270", context); return null; } else if ("XPTY0020".equals(e.getErrorCodeLocalPart())) { dynamicError( "Cannot call the key() function when the context item is an atomic value", "XTDE1270", context); return null; } throw e; } NodeInfo origin = (NodeInfo) arg2; NodeInfo root = origin.getRoot(); if (root.getNodeKind() != Type.DOCUMENT) { dynamicError( "In the key() function," + " the node supplied in the third argument (or the context node if absent)" + " must be in a tree whose root is a document node", "XTDE1270", context); return null; } DocumentInfo doc = (DocumentInfo) root; int fprint = keyFingerprint; if (fprint == -1) { String givenkeyname = argument[0].evaluateItem(context).getStringValue(); try { fprint = controller .getNamePool() .allocateLexicalQName( givenkeyname, false, nsContext, controller.getConfiguration().getNameChecker()) & NamePool.FP_MASK; } catch (XPathException err) { dynamicError("Invalid key name: " + err.getMessage(), "XTDE1260", context); } if (fprint == -1) { dynamicError("Key '" + givenkeyname + "' has not been defined", "XTDE1260", context); return null; } } // if (internal) { // System.err.println("Using key " + fprint + " on doc " + doc); // } // If the second argument is a singleton, we evaluate the function // directly; otherwise we recurse to evaluate it once for each Item // in the sequence. Expression expression = argument[1]; SequenceIterator allResults; if (Cardinality.allowsMany(expression.getCardinality())) { final XPathContext keyContext = context; final DocumentInfo document = doc; final KeyManager keyManager = controller.getKeyManager(); MappingFunction map = new MappingFunction() { // Map a value to the sequence of nodes having that value as a key value public Object map(Item item) throws XPathException { return keyManager.selectByKey( keyFingerprint, document, (AtomicValue) item, keyContext); } }; SequenceIterator keys = argument[1].iterate(context); SequenceIterator allValues = new MappingIterator(keys, map); allResults = new DocumentOrderIterator(allValues, LocalOrderComparer.getInstance()); } else { try { AtomicValue keyValue = (AtomicValue) argument[1].evaluateItem(context); if (keyValue == null) { return EmptyIterator.getInstance(); } KeyManager keyManager = controller.getKeyManager(); allResults = keyManager.selectByKey(fprint, doc, keyValue, context); } catch (XPathException e) { if (e.getLocator() == null) { e.setLocator(this); } throw e; } } if (origin == doc) { return allResults; } SubtreeFilter filter = new SubtreeFilter(); filter.origin = origin; return new ItemMappingIterator(allResults, filter); }