/** * Get an iterator over the results of the expression. This returns results without any conversion * of the returned items to "native" Java classes. The iterator will deliver a sequence of Item * objects, each item being either a NodeInfo (representing a node) or an AtomicValue * (representing an atomic value). * * <p> * * <p>To get the results of the query in the form of an XML document in which each item is wrapped * by an element indicating its type, use: * * <p> * * <p><code>QueryResult.wrap(iterator(env))</code> * * <p> * * <p>To serialize the results to a file, use the QueryResult.serialize() method. * * @param env Provides the dynamic query evaluation context * @return an iterator over the results of the query. The class SequenceIterator is modeled on the * standard Java Iterator class, but has extra functionality and can throw exceptions when * errors occur. * @throws XPathException if a dynamic error occurs in evaluating the query. Some dynamic errors * will not be reported by this method, but will only be reported when the individual items of * the result are accessed using the returned iterator. */ public SequenceIterator iterator(DynamicQueryContext env) throws XPathException { if (isUpdating) { throw new XPathException("Cannot call iterator() on an updating query"); } Controller controller = newController(); initializeController(env, controller); try { Item contextItem = env.getContextItem(); // Bindery bindery = controller.getBindery(); // bindery.openStackFrame(); controller.defineGlobalParameters(); XPathContextMajor context = controller.newXPathContext(); if (contextItem != null) { if (!staticContext .getUserQueryContext() .getRequiredContextItemType() .matchesItem(contextItem, false, env.getConfiguration())) { throw new XPathException( "The supplied context item does not match the required context item type"); } UnfailingIterator single = SingletonIterator.makeIterator(contextItem); single.next(); context.setCurrentIterator(single); controller.setInitialContextItem(contextItem); } // In tracing/debugging mode, evaluate all the global variables first if (controller.getTraceListener() != null) { controller.preEvaluateGlobals(context); } context.openStackFrame(stackFrameMap); SequenceIterator iterator = expression.iterate(context); return new ErrorReportingIterator(iterator, controller.getErrorListener()); } catch (XPathException err) { TransformerException terr = err; while (terr.getException() instanceof TransformerException) { terr = (TransformerException) terr.getException(); } XPathException de = XPathException.makeXPathException(terr); controller.reportFatalError(de); throw de; } }
/** * Run the query in pull mode. * * <p> * * <p>For maximum effect this method should be used when lazyConstructionMode has been set in the * Configuration. * * <p> * * <p><b>Note: this method usually has very similar performance to the {@link * #run(DynamicQueryContext,javax.xml.transform.Result,java.util.Properties)} method (which does * the same thing), but sometimes it is significantly slower. Therefore, the run() method is * preferred.</b> * * @param dynamicEnv the dynamic context for query evaluation * @param destination the destination of the query results * @param outputProperties the serialization parameters * @see Configuration#setLazyConstructionMode(boolean) */ public void pull(DynamicQueryContext dynamicEnv, Result destination, Properties outputProperties) throws XPathException { if (isUpdating) { throw new XPathException("Cannot call pull() on an updating query"); } Configuration config = dynamicEnv.getConfiguration(); try { Controller controller = newController(); // initializeController(dynamicEnv, controller); EventIterator iter = iterateEvents(controller, dynamicEnv); // iter = new Decomposer(iter, config); Properties actualProperties = validateOutputProperties(controller, outputProperties); SerializerFactory sf = config.getSerializerFactory(); PipelineConfiguration pipe = config.makePipelineConfiguration(); pipe.setSerializing(true); Receiver receiver = sf.getReceiver(destination, pipe, actualProperties); receiver = new NamespaceReducer(receiver); if ("yes".equals(actualProperties.getProperty(SaxonOutputKeys.WRAP))) { receiver = new SequenceWrapper(receiver); // receiver = new TracingFilter(receiver); } else { receiver = new TreeReceiver(receiver); } EventIteratorToReceiver.copy(iter, (SequenceReceiver) receiver); } catch (XPathException err) { config.reportFatalError(err); throw err; } }
private XPathContextMajor initialContext(DynamicQueryContext dynamicEnv, Controller controller) throws XPathException { Item contextItem = dynamicEnv.getContextItem(); controller.defineGlobalParameters(); XPathContextMajor context = controller.newXPathContext(); if (contextItem != null) { if (!staticContext .getUserQueryContext() .getRequiredContextItemType() .matchesItem(contextItem, false, dynamicEnv.getConfiguration())) { throw new XPathException( "The supplied context item does not match the required context item type"); } UnfailingIterator single = SingletonIterator.makeIterator(contextItem); single.next(); context.setCurrentIterator(single); controller.setInitialContextItem(contextItem); } return context; }
private void initializeController(DynamicQueryContext env, Controller controller) { HashMap parameters = env.getParameters(); if (parameters != null) { Iterator iter = parameters.keySet().iterator(); while (iter.hasNext()) { String paramName = (String) iter.next(); Object paramValue = parameters.get(paramName); controller.setParameter(paramName, paramValue); } } controller.setURIResolver(env.getURIResolver()); controller.setErrorListener(env.getErrorListener()); controller.addTraceListener(env.getTraceListener()); controller.setTraceFunctionDestination(env.getTraceFunctionDestination()); DateTimeValue currentDateTime = env.getCurrentDateTime(); if (currentDateTime != null) { try { controller.setCurrentDateTime(currentDateTime); } catch (XPathException e) { throw new AssertionError(e); // the value should already have been checked } } }
/** * Support method for main program. This support method can also be invoked from subclasses that * support the same command line interface * * @param args the command-line arguments * @param name name of the class, to be used in error messages */ protected void doQuery(String args[], String name) { boolean showTime = false; int repeat = 1; String sourceFileName = null; String queryFileName = null; File sourceFile; File outputFile; boolean useURLs = false; String outputFileName = null; boolean explain = false; boolean wrap = false; boolean pullMode = false; boolean schemaAware = false; for (int i = 0; i < args.length; i++) { if (args[i].equals("-sa")) { schemaAware = true; } else if (args[i].equals("-val")) { schemaAware = true; } else if (args[i].equals("-vlax")) { schemaAware = true; } else if (args[i].equals("-p")) { schemaAware = true; } } config = makeConfiguration(schemaAware); config.setHostLanguage(Configuration.XQUERY); StaticQueryContext staticEnv = new StaticQueryContext(config); DynamicQueryContext dynamicEnv = new DynamicQueryContext(config); Properties outputProps = new Properties(); // Check the command-line arguments. try { int i = 0; while (i < args.length) { if (args[i].charAt(0) == '-') { if (args[i].equals("-cr")) { i++; if (args.length < i + 1) { badUsage(name, "No output file name"); } String crclass = args[i++]; Object resolver = config.getInstance(crclass, null); if (!(resolver instanceof CollectionURIResolver)) { quit(crclass + " is not a CollectionURIResolver", 2); } config.setCollectionURIResolver((CollectionURIResolver) resolver); } else if (args[i].equals("-ds")) { config.setTreeModel(Builder.LINKED_TREE); i++; } else if (args[i].equals("-dt")) { config.setTreeModel(Builder.TINY_TREE); i++; } else if (args[i].equals("-e")) { explain = true; i++; } else if (args[i].equals("-l")) { config.setLineNumbering(true); i++; } else if (args[i].equals("-3")) { // undocumented option: do it thrice i++; repeat = 3; } else if (args[i].equals("-9")) { // undocumented option: do it nine times i++; repeat = 9; } else if (args[i].equals("-mr")) { i++; if (args.length < i + 1) { badUsage(name, "No ModuleURIResolver class"); } String r = args[i++]; config.setModuleURIResolver(r); } else if (args[i].equals("-noext")) { i++; config.setAllowExternalFunctions(false); } else if (args[i].equals("-o")) { i++; if (args.length < i + 1) { badUsage(name, "No output file name"); } outputFileName = args[i++]; } else if (args[i].equals("-p")) { i++; setPOption(config); useURLs = true; } else if (args[i].equals("-pull")) { i++; pullMode = true; } else if (args[i].equals("-r")) { i++; if (args.length < i + 1) { badUsage(name, "No URIResolver class"); } String r = args[i++]; config.setURIResolver(config.makeURIResolver(r)); dynamicEnv.setURIResolver(config.makeURIResolver(r)); } else if (args[i].equals("-s")) { i++; if (args.length < i + 1) { badUsage(name, "No source file name"); } sourceFileName = args[i++]; } else if (args[i].equals("-sa")) { // already handled i++; } else if (args[i].equals("-snone")) { config.setStripsWhiteSpace(Whitespace.NONE); i++; } else if (args[i].equals("-sall")) { config.setStripsWhiteSpace(Whitespace.ALL); i++; } else if (args[i].equals("-signorable")) { config.setStripsWhiteSpace(Whitespace.IGNORABLE); i++; } else if (args[i].equals("-strip")) { // retained for compatibility config.setStripsWhiteSpace(Whitespace.ALL); i++; } else if (args[i].equals("-t")) { System.err.println(config.getProductTitle()); // System.err.println("Java version " + System.getProperty("java.version")); System.err.println(config.getPlatform().getPlatformVersion()); config.setTiming(true); showTime = true; i++; } else if (args[i].equals("-T")) { config.setTraceListener(new XQueryTraceListener()); i++; } else if (args[i].equals("-TJ")) { i++; config.setTraceExternalFunctions(true); } else if (args[i].equals("-TL")) { if (args.length < i + 2) { badUsage(name, "No TraceListener class specified"); } TraceListener traceListener = config.makeTraceListener(args[++i]); config.setTraceListener(traceListener); config.setLineNumbering(true); i++; } else if (args[i].equals("-u")) { useURLs = true; i++; } else if (args[i].equals("-untyped")) { // TODO: this is an experimental undocumented option. It should be checked for // consistency config.setAllNodesUntyped(true); i++; } else if (args[i].equals("-v")) { config.setValidation(true); i++; } else if (args[i].equals("-val")) { if (schemaAware) { config.setSchemaValidationMode(Validation.STRICT); } else { quit("The -val option requires a schema-aware processor", 2); } i++; } else if (args[i].equals("-vlax")) { if (schemaAware) { config.setSchemaValidationMode(Validation.LAX); } else { quit("The -vlax option requires a schema-aware processor", 2); } i++; } else if (args[i].equals("-vw")) { if (schemaAware) { config.setValidationWarnings(true); } else { quit("The -vw option requires a schema-aware processor", 2); } i++; } else if (args[i].equals("-wrap")) { wrap = true; i++; } else if (args[i].equals("-1.1")) { config.setXMLVersion(Configuration.XML11); i++; } else if (args[i].equals("-?")) { badUsage(name, ""); } else if (args[i].equals("-")) { queryFileName = "-"; i++; } else { badUsage(name, "Unknown option " + args[i]); } } else { break; } } if (!("-".equals(queryFileName))) { if (args.length < i + 1) { badUsage(name, "No query file name"); } queryFileName = args[i++]; } for (int p = i; p < args.length; p++) { String arg = args[p]; int eq = arg.indexOf("="); if (eq < 1 || eq >= arg.length() - 1) { badUsage(name, "Bad param=value pair on command line: " + arg); } String argname = arg.substring(0, eq); if (argname.startsWith("!")) { // parameters starting with "!" are taken as output properties outputProps.setProperty(argname.substring(1), arg.substring(eq + 1)); } else if (argname.startsWith("+")) { // parameters starting with "+" are taken as input documents Object sources = Transform.loadDocuments(arg.substring(eq + 1), useURLs, config, true); dynamicEnv.setParameter(argname.substring(1), sources); } else { dynamicEnv.setParameter(argname, new UntypedAtomicValue(arg.substring(eq + 1))); } } config.displayLicenseMessage(); if (pullMode) { config.setLazyConstructionMode(true); } Source sourceInput = null; if (sourceFileName != null) { if (useURLs || sourceFileName.startsWith("http:") || sourceFileName.startsWith("file:")) { sourceInput = config.getURIResolver().resolve(sourceFileName, null); if (sourceInput == null) { sourceInput = config.getSystemURIResolver().resolve(sourceFileName, null); } } else if (sourceFileName.equals("-")) { // take input from stdin sourceInput = new StreamSource(System.in); } else { sourceFile = new File(sourceFileName); if (!sourceFile.exists()) { quit("Source file " + sourceFile + " does not exist", 2); } if (config.getPlatform() instanceof JavaPlatform) { InputSource eis = new InputSource(sourceFile.toURI().toString()); sourceInput = new SAXSource(eis); } else { sourceInput = new StreamSource(sourceFile.toURI().toString()); } } } long startTime = (new Date()).getTime(); if (showTime) { System.err.println("Compiling query from " + queryFileName); } XQueryExpression exp; try { if (queryFileName.equals("-")) { Reader queryReader = new InputStreamReader(System.in); exp = staticEnv.compileQuery(queryReader); } else if (queryFileName.startsWith("{") && queryFileName.endsWith("}")) { // query is inline on the command line String q = queryFileName.substring(1, queryFileName.length() - 1); exp = staticEnv.compileQuery(q); } else if (useURLs || queryFileName.startsWith("http:") || queryFileName.startsWith("file:")) { ModuleURIResolver resolver = config.getModuleURIResolver(); String[] locations = {queryFileName}; Source[] sources = resolver.resolve(null, null, locations); if (sources.length != 1 || !(sources[0] instanceof StreamSource)) { quit("Module URI Resolver must return a single StreamSource", 2); } String queryText = QueryReader.readSourceQuery((StreamSource) sources[0], config.getNameChecker()); exp = staticEnv.compileQuery(queryText); } else { InputStream queryStream = new FileInputStream(queryFileName); staticEnv.setBaseURI(new File(queryFileName).toURI().toString()); exp = staticEnv.compileQuery(queryStream, null); } staticEnv = exp.getStaticContext(); // the original staticContext is copied if (showTime) { long endTime = (new Date()).getTime(); System.err.println("Compilation time: " + (endTime - startTime) + " milliseconds"); startTime = endTime; } } catch (XPathException err) { int line = -1; String module = null; if (err.getLocator() != null) { line = err.getLocator().getLineNumber(); module = err.getLocator().getSystemId(); } if (err.hasBeenReported()) { quit("Failed to compile query", 2); } else { if (line == -1) { System.err.println("Failed to compile query: " + err.getMessage()); } else { System.err.println("Static error at line " + line + " of " + module + ':'); System.err.println(err.getMessage()); } } exp = null; System.exit(2); } if (explain) { staticEnv.getExecutable().getKeyManager().explainKeys(config); staticEnv.explainGlobalVariables(); staticEnv.explainGlobalFunctions(); exp.explain(staticEnv.getConfiguration()); } OutputStream destination; if (outputFileName != null) { outputFile = new File(outputFileName); if (outputFile.isDirectory()) { quit("Output is a directory", 2); } destination = new FileOutputStream(outputFile); } else { destination = System.out; } for (int r = 0; r < repeat; r++) { // repeat is for internal testing/timing if (sourceInput != null) { if (showTime) { System.err.println("Processing " + sourceInput.getSystemId()); } DocumentInfo doc = staticEnv.buildDocument(sourceInput); dynamicEnv.setContextItem(doc); } try { if (wrap) { SequenceIterator results = exp.iterator(dynamicEnv); DocumentInfo resultDoc = QueryResult.wrap(results, config); QueryResult.serialize(resultDoc, new StreamResult(destination), outputProps, config); destination.close(); } else if (pullMode) { if (wrap) { outputProps.setProperty(SaxonOutputKeys.WRAP, "yes"); } try { exp.pull(dynamicEnv, new StreamResult(destination), outputProps); } catch (XPathException err) { config.reportFatalError(err); throw err; } } else { exp.run(dynamicEnv, new StreamResult(destination), outputProps); } } catch (TerminationException err) { throw err; } catch (XPathException err) { if (err.hasBeenReported()) { throw new DynamicError("Run-time errors were reported"); } else { throw err; } } if (showTime) { long endTime = (new Date()).getTime(); System.err.println("Execution time: " + (endTime - startTime) + " milliseconds"); startTime = endTime; } } } catch (TerminationException err) { quit(err.getMessage(), 1); } catch (XPathException err) { quit("Query processing failed: " + err.getMessage(), 2); } catch (TransformerFactoryConfigurationError err) { err.printStackTrace(); quit("Query processing failed", 2); } catch (Exception err2) { err2.printStackTrace(); quit("Fatal error during transformation: " + err2.getMessage(), 2); } }