public void run() throws SaxonApiException { super.run(); RuntimeValue wrapperNameValue = getOption(_wrapper); String wrapperNameStr = wrapperNameValue.getString(); String wpfx = getOption(_wrapper_prefix, (String) null); String wns = getOption(_wrapper_namespace, (String) null); if (wpfx != null && wns == null) { throw XProcException.dynamicError( 34, step.getNode(), "You can't specify a prefix without a namespace"); } if (wns != null && wrapperNameStr.contains(":")) { throw XProcException.dynamicError( 34, step.getNode(), "You can't specify a namespace if the wrapper name contains a colon"); } if (wrapperNameStr.contains(":")) { wrapper = new QName(wrapperNameStr, wrapperNameValue.getNode()); } else { wrapper = new QName(wpfx == null ? "" : wpfx, wns, wrapperNameStr); } groupAdjacent = getOption(_group_adjacent); if (groupAdjacent != null) { runAdjacent(); } else { runSimple(); } }
private void runAdjacent() throws SaxonApiException { TreeWriter treeWriter = null; String last = null; boolean open = false; int count = 0; while (source.moreDocuments()) { count++; source.read(); } source.resetReader(); DocumentSequenceIterator xsi = new DocumentSequenceIterator(); // See below xsi.setLast(count); int pos = 0; while (source.moreDocuments()) { XdmNode node = source.read(); pos++; Item item = null; try { XPathCompiler xcomp = runtime.getProcessor().newXPathCompiler(); xcomp.setBaseURI(step.getNode().getBaseURI()); for (String prefix : groupAdjacent.getNamespaceBindings().keySet()) { xcomp.declareNamespace(prefix, groupAdjacent.getNamespaceBindings().get(prefix)); } XPathExecutable xexec = xcomp.compile(groupAdjacent.getString()); // From Michael Kay: http://markmail.org/message/vkb2vaq2miylgndu // // Underneath the s9api XPathExecutable is a net.sf.saxon.sxpath.XPathExpression. XPathExpression xexpr = xexec.getUnderlyingExpression(); // Call createDynamicContext() on this to get an XPathDynamicContext object; XPathDynamicContext xdc = xexpr.createDynamicContext(node.getUnderlyingNode()); // call getXPathContextObject() on that to get the underlying XPathContext. XPathContext xc = xdc.getXPathContextObject(); // Then call XPathContext.setCurrentIterator() // to supply a SequenceIterator whose current() and position() methods return // the context item and position respectively. If there's any risk that the // expression will call the last() method, then it's simplest to make your // iterator's getProperties() return LAST_POSITION_FINDER, and implement the // LastPositionFinder interface, in which case last() will be implemented by // calling the iterator's getLastPosition() method. (Otherwise last() is // implemented by calling getAnother() to clone the iterator and calling next() // on the clone until the end of the sequence is reached). xsi.setPosition(pos); xsi.setItem(node.getUnderlyingNode()); xc.setCurrentIterator(xsi); // Then evaluate the expression by calling iterate() on the // net.sf.saxon.sxpath.XPathExpression object. SequenceIterator results = xexpr.iterate(xdc); item = results.next(); if (item == null) { throw new XProcException( step.getNode(), "The group-adjacent expression returned nothing."); } if (results.next() != null) { throw new XProcException( step.getNode(), "Didn't expect group-adjacent to return a sequence!"); } } catch (XPathException xe) { throw new XProcException(xe); } // // Good luck! // // FIXME: Compute effective boolean value in a more robust way String cur = item.getStringValue(); if (last != null) { if (last.equals(cur)) { treeWriter.addSubtree(node); } else { if (open) { open = false; treeWriter.addEndElement(); treeWriter.endDocument(); result.write(treeWriter.getResult()); } } } if (last == null || !last.equals(cur)) { last = cur; open = true; treeWriter = new TreeWriter(runtime); treeWriter.startDocument(step.getNode().getBaseURI()); treeWriter.addStartElement(wrapper); treeWriter.startContent(); treeWriter.addSubtree(node); } } if (open) { open = false; treeWriter.addEndElement(); treeWriter.endDocument(); result.write(treeWriter.getResult()); } }
public boolean processStartElement(XdmNode node) { // Use a TreeWriter to make the matching node into a proper document TreeWriter treeWriter = new TreeWriter(runtime); treeWriter.startDocument(node.getBaseURI()); treeWriter.addSubtree(node); treeWriter.endDocument(); current.resetWriter(); current.write(treeWriter.getResult()); finest(step.getNode(), "Viewport copy matching node to " + current); sequencePosition++; runtime.getXProcData().setIterationPosition(sequencePosition); // Calculate all the variables inScopeOptions = parent.getInScopeOptions(); for (Variable var : step.getVariables()) { RuntimeValue value = computeValue(var); if ("p3".equals(var.getName().getLocalName())) { System.err.println("DEBUG ME1: " + value.getString()); } inScopeOptions.put(var.getName(), value); } try { for (XStep step : subpipeline) { step.reset(); step.run(); } } catch (SaxonApiException sae) { throw new XProcException(sae); } try { int count = 0; for (String port : inputs.keySet()) { if (port.startsWith("|")) { for (ReadablePipe reader : inputs.get(port)) { while (reader.moreDocuments()) { count++; if (count > 1) { XOutput output = getOutput(port.substring(1)); if (!output.getSequence()) { throw XProcException.dynamicError(7); } } XdmNode doc = reader.read(); matcher.addSubtree(doc); } reader.resetReader(); } } } } catch (SaxonApiException sae) { throw new XProcException(sae); } return false; }