1.1 --- a/java/alt2xml-out-xpath/src/cz/frantovo/alt2xml/out/xpath/XPathAction.java Tue Oct 28 17:53:24 2014 +0100
1.2 +++ b/java/alt2xml-out-xpath/src/cz/frantovo/alt2xml/out/xpath/XPathAction.java Wed Oct 29 01:25:06 2014 +0100
1.3 @@ -21,17 +21,32 @@
1.4 import cz.frantovo.alt2xml.out.ActionContext;
1.5 import cz.frantovo.alt2xml.out.OutputActionException;
1.6 import java.io.PrintWriter;
1.7 +import java.io.StringWriter;
1.8 import java.util.Arrays;
1.9 import java.util.HashMap;
1.10 import java.util.List;
1.11 import java.util.Map;
1.12 +import java.util.logging.Level;
1.13 +import java.util.logging.Logger;
1.14 +import javax.xml.transform.OutputKeys;
1.15 +import javax.xml.transform.Transformer;
1.16 +import javax.xml.transform.TransformerConfigurationException;
1.17 +import javax.xml.transform.TransformerException;
1.18 +import javax.xml.transform.TransformerFactory;
1.19 +import javax.xml.transform.TransformerFactoryConfigurationError;
1.20 import javax.xml.transform.dom.DOMResult;
1.21 +import javax.xml.transform.dom.DOMSource;
1.22 +import javax.xml.transform.stream.StreamResult;
1.23 import javax.xml.xpath.XPath;
1.24 +import javax.xml.xpath.XPathConstants;
1.25 import javax.xml.xpath.XPathExpression;
1.26 import javax.xml.xpath.XPathExpressionException;
1.27 import javax.xml.xpath.XPathFactory;
1.28 import javax.xml.xpath.XPathVariableResolver;
1.29 +import org.w3c.dom.Attr;
1.30 +import org.w3c.dom.Element;
1.31 import org.w3c.dom.Node;
1.32 +import org.w3c.dom.NodeList;
1.33
1.34 /**
1.35 *
1.36 @@ -42,9 +57,14 @@
1.37 public static final String PARAMETER_TYPED_PARAMETERS = "typed-parameters";
1.38 public static final String PARAMETER_LINE_BREAK = "line-break";
1.39 public static final String PARAMETER_ENVIRONMENT_VARIABLES = "environment-variables";
1.40 + public static final String PARAMETER_NODE_SET = "node-set";
1.41 + private static final Logger log = Logger.getLogger(XPathAction.class.getName());
1.42 private final boolean typedParameters;
1.43 private final boolean lineBreak;
1.44 private final boolean environmentVariables;
1.45 + private final boolean nodeSet;
1.46 + private final TransformerFactory transformerFactory;
1.47 + private final Transformer copyTransformer;
1.48 private final XPathFactory xpathFactory;
1.49 private final XPath xpath;
1.50 private final String expressionString;
1.51 @@ -54,6 +74,14 @@
1.52 xpathFactory = XPathFactory.newInstance();
1.53 xpath = xpathFactory.newXPath();
1.54
1.55 + try {
1.56 + transformerFactory = TransformerFactory.newInstance();
1.57 + copyTransformer = transformerFactory.newTransformer();
1.58 + copyTransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
1.59 + } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
1.60 + throw new OutputActionException("Unable to initialize XSLT copying transformer", e);
1.61 + }
1.62 +
1.63 final List<String> actionData = getActionContext().getActionData();
1.64
1.65 if (actionData.size() < 1) {
1.66 @@ -63,6 +91,7 @@
1.67 typedParameters = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_TYPED_PARAMETERS));
1.68 lineBreak = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_LINE_BREAK, Boolean.TRUE.toString()));
1.69 environmentVariables = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_ENVIRONMENT_VARIABLES, Boolean.FALSE.toString()));
1.70 + nodeSet = Boolean.parseBoolean(actionContext.getActionProperties().getProperty(PARAMETER_NODE_SET, Boolean.FALSE.toString()));
1.71
1.72 Map<String, Object> xpathParameters = new HashMap<>();
1.73
1.74 @@ -139,6 +168,16 @@
1.75 }
1.76 }
1.77
1.78 + private String nodeToString(Node node) throws OutputActionException {
1.79 + try {
1.80 + StringWriter w = new StringWriter();
1.81 + copyTransformer.transform(new DOMSource(node), new StreamResult(w));
1.82 + return w.toString();
1.83 + } catch (TransformerException e) {
1.84 + throw new OutputActionException("Unable to convert node to string", e);
1.85 + }
1.86 + }
1.87 +
1.88 @Override
1.89 public void run(DOMResult domResult) throws OutputActionException {
1.90 XPathExpression xpathExpression = null;
1.91 @@ -153,12 +192,42 @@
1.92 throw new OutputActionException("Unable to compile XPath: " + expressionString, e);
1.93 }
1.94
1.95 - String result = xpathExpression.evaluate(document);
1.96 try (PrintWriter out = new PrintWriter(getActionContext().getOutputStream())) {
1.97 - out.print(result);
1.98 - if (lineBreak) {
1.99 - out.println();
1.100 +
1.101 + if (nodeSet) {
1.102 + NodeList result = (NodeList) xpathExpression.evaluate(document, XPathConstants.NODESET);
1.103 + for (int i = 0; i < result.getLength(); i++) {
1.104 + Node node = result.item(i);
1.105 +
1.106 + log.log(Level.FINE, "Node type: {0}", node.getClass());
1.107 +
1.108 + final String stringValue;
1.109 +
1.110 + if (node instanceof Attr) {
1.111 + Attr attribute = (Attr) node;
1.112 + stringValue = attribute.getValue();
1.113 + } else if (node instanceof Element) {
1.114 + stringValue = nodeToString(node);
1.115 + /**
1.116 + * TODO: print/log node separator
1.117 + */
1.118 + } else {
1.119 + stringValue = String.valueOf(node);
1.120 + }
1.121 +
1.122 + out.print(stringValue);
1.123 + if (lineBreak) {
1.124 + out.println();
1.125 + }
1.126 + }
1.127 + } else {
1.128 + log.log(Level.FINE, "String value, no node-set");
1.129 + out.print(xpathExpression.evaluate(document));
1.130 + if (lineBreak) {
1.131 + out.println();
1.132 + }
1.133 }
1.134 +
1.135 }
1.136 } catch (XPathExpressionException e) {
1.137 throw new OutputActionException("Unable to evaluate XPath: " + xpathExpression, e);