# HG changeset patch # User František Kučera # Date 1414542306 -3600 # Node ID e62a3e4982121453512b14ea7201d7b7d546a1d2 # Parent 33b2441a6d3661a9035335b2f3101fd86732e47d out-xpath: support also node-set (not only primitive type results) diff -r 33b2441a6d36 -r e62a3e498212 java/alt2xml-out-xpath/src/cz/frantovo/alt2xml/out/xpath/XPathAction.java --- a/java/alt2xml-out-xpath/src/cz/frantovo/alt2xml/out/xpath/XPathAction.java Tue Oct 28 17:53:24 2014 +0100 +++ b/java/alt2xml-out-xpath/src/cz/frantovo/alt2xml/out/xpath/XPathAction.java Wed Oct 29 01:25:06 2014 +0100 @@ -21,17 +21,32 @@ import cz.frantovo.alt2xml.out.ActionContext; import cz.frantovo.alt2xml.out.OutputActionException; import java.io.PrintWriter; +import java.io.StringWriter; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathVariableResolver; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * @@ -42,9 +57,14 @@ public static final String PARAMETER_TYPED_PARAMETERS = "typed-parameters"; public static final String PARAMETER_LINE_BREAK = "line-break"; public static final String PARAMETER_ENVIRONMENT_VARIABLES = "environment-variables"; + public static final String PARAMETER_NODE_SET = "node-set"; + private static final Logger log = Logger.getLogger(XPathAction.class.getName()); private final boolean typedParameters; private final boolean lineBreak; private final boolean environmentVariables; + private final boolean nodeSet; + private final TransformerFactory transformerFactory; + private final Transformer copyTransformer; private final XPathFactory xpathFactory; private final XPath xpath; private final String expressionString; @@ -54,6 +74,14 @@ xpathFactory = XPathFactory.newInstance(); xpath = xpathFactory.newXPath(); + try { + transformerFactory = TransformerFactory.newInstance(); + copyTransformer = transformerFactory.newTransformer(); + copyTransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) { + throw new OutputActionException("Unable to initialize XSLT copying transformer", e); + } + final List actionData = getActionContext().getActionData(); if (actionData.size() < 1) { @@ -63,6 +91,7 @@ typedParameters = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_TYPED_PARAMETERS)); lineBreak = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_LINE_BREAK, Boolean.TRUE.toString())); environmentVariables = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_ENVIRONMENT_VARIABLES, Boolean.FALSE.toString())); + nodeSet = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_NODE_SET, Boolean.FALSE.toString())); Map xpathParameters = new HashMap<>(); @@ -139,6 +168,16 @@ } } + private String nodeToString(Node node) throws OutputActionException { + try { + StringWriter w = new StringWriter(); + copyTransformer.transform(new DOMSource(node), new StreamResult(w)); + return w.toString(); + } catch (TransformerException e) { + throw new OutputActionException("Unable to convert node to string", e); + } + } + @Override public void run(DOMResult domResult) throws OutputActionException { XPathExpression xpathExpression = null; @@ -153,12 +192,42 @@ throw new OutputActionException("Unable to compile XPath: " + expressionString, e); } - String result = xpathExpression.evaluate(document); try (PrintWriter out = new PrintWriter(getActionContext().getOutputStream())) { - out.print(result); - if (lineBreak) { - out.println(); + + if (nodeSet) { + NodeList result = (NodeList) xpathExpression.evaluate(document, XPathConstants.NODESET); + for (int i = 0; i < result.getLength(); i++) { + Node node = result.item(i); + + log.log(Level.FINE, "Node type: {0}", node.getClass()); + + final String stringValue; + + if (node instanceof Attr) { + Attr attribute = (Attr) node; + stringValue = attribute.getValue(); + } else if (node instanceof Element) { + stringValue = nodeToString(node); + /** + * TODO: print/log node separator + */ + } else { + stringValue = String.valueOf(node); + } + + out.print(stringValue); + if (lineBreak) { + out.println(); + } + } + } else { + log.log(Level.FINE, "String value, no node-set"); + out.print(xpathExpression.evaluate(document)); + if (lineBreak) { + out.println(); + } } + } } catch (XPathExpressionException e) { throw new OutputActionException("Unable to evaluate XPath: " + xpathExpression, e);