From 45a7e60ae46461cc820a4dcdc9d611ec58088bf6 Mon Sep 17 00:00:00 2001 From: Adam Bem Date: Thu, 9 Feb 2023 13:22:33 +0100 Subject: [PATCH] Replaced xpath handling implementation --- .../com/r11/tools/xslt/processors/Xalan.java | 74 ++++++++++++++++--- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java b/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java index 42db619..c0fb631 100644 --- a/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java +++ b/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java @@ -1,8 +1,12 @@ package com.r11.tools.xslt.processors; +import net.sf.saxon.lib.RawResult; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.xpath.XPathAPI; import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.traversal.NodeIterator; import org.xml.sax.InputSource; import javax.xml.XMLConstants; @@ -19,8 +23,7 @@ import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; -import java.io.StringReader; -import java.io.StringWriter; +import java.io.*; /** * Handler for Xalan engine @@ -53,6 +56,13 @@ public class Xalan { return sw.toString(); } + private static boolean isTextNode(Node n) { + if (n == null) + return false; + short nodeType = n.getNodeType(); + return nodeType == Node.CDATA_SECTION_NODE || nodeType == Node.TEXT_NODE; + } + /** * Process xpath and return either node or wrapped atomic value * @deprecated @@ -62,16 +72,60 @@ public class Xalan { * @return xml processed using given xpath * @throws Exception thrown on node building errors or invalid xpath */ - public static String processXPath(String data, String transform) throws Exception{ - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); + public static String processXPath(String data, String transform) throws Exception { +// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); +// DocumentBuilder builder = factory.newDocumentBuilder(); +// +// XPath xpath = XPathFactory.newInstance().newXPath(); +// +// xpath.setNamespaceContext(new XalanNamespaceResolver(builder.parse(new InputSource(new StringReader(data))), true)); +// XPathExpression exp = xpath.compile(transform); +// exp.evaluate(new InputSource(new StringReader(data)), XPathConstants.NODESET); +// return exp.evaluate(new InputSource(new StringReader(data))); - XPath xpath = XPathFactory.newInstance().newXPath(); + //data = "/home/adam/Programowanie/Java/XML Tools/release11-tools-web/SampleData/book.xml"; + //transform = "/books/book[name = 'Hamlet']"; - xpath.setNamespaceContext(new XalanNamespaceResolver(builder.parse(new InputSource(new StringReader(data))), true)); - XPathExpression exp = xpath.compile(transform); - exp.evaluate(new InputSource(new StringReader(data)), XPathConstants.NODESET); - return exp.evaluate(new InputSource(new StringReader(data))); + + // Set up a DOM tree to query. + InputSource in = new InputSource(new StringReader(data)); + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setNamespaceAware(true); + Document doc = dfactory.newDocumentBuilder().parse(in); + + // Set up an identity transformer to use as serializer. + Transformer serializer = TransformerFactory.newInstance().newTransformer(); + serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + + // Use the simple XPath API to select a nodeIterator. + NodeIterator nl = XPathAPI.selectNodeIterator(doc, transform); + + // Serialize the found nodes to result object. + StringBuilder result = new StringBuilder(); + Node n; + while ((n = nl.nextNode())!= null) { + StringBuilder sb; + if (isTextNode(n)) { + // DOM may have more than one node corresponding to a + // single XPath text node. Coalesce all contiguous text nodes + // at this level + sb = new StringBuilder(n.getNodeValue()); + for ( + Node nn = n.getNextSibling(); + isTextNode(nn); + nn = nn.getNextSibling() + ) { + result.append(nn.getNodeValue()); + } + } else { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + serializer.transform(new DOMSource(n), new StreamResult(new OutputStreamWriter(outputStream))); + result.append(outputStream); + + } + result.append("\n"); + } + return result.toString(); } /**