package de.dpa.oss.metadata.mapper.common;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import java.io.Reader;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;
/**
* TODO review/refactoring
*
* @author Ben Asmussen
*/
public class XmlUtils
{
/**
* Creates an XPath object with a custom NamespaceContext given the Node to
* operate on
* <p/>
* the Node or document to operate on. Note that namespace
* handling will not work if a Node fragment is passed in
*
* @return a new XPath object
*/
public static XPath createXPath()
{
return XPathFactory.newInstance().newXPath();
}
public static Document toDocument(String xml) throws Exception
{
// default we ignore namespaces
return toDocument(xml, false);
}
public static Document toDocument(String xml, boolean namespaceAware) throws Exception
{
return toDocument(xml, namespaceAware, false);
}
public static Document toDocument(String xml, boolean namespaceAware, boolean ignoreDtd) throws Exception
{
Reader input = new StringReader(xml);
InputSource is = new InputSource(input);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(namespaceAware);
// ignore dtd files
if (ignoreDtd)
{
dbf.setValidating(false);
dbf.setFeature("http://xml.org/sax/features/namespaces", false);
dbf.setFeature("http://xml.org/sax/features/validation", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
}
DocumentBuilder db = dbf.newDocumentBuilder();
db.setErrorHandler(new ErrorHandler()
{
public void warning(SAXParseException exception) throws SAXException
{
throw exception;
}
public void fatalError(SAXParseException exception) throws SAXException
{
throw exception;
}
public void error(SAXParseException exception) throws SAXException
{
throw exception;
}
});
return db.parse(is);
}
public static String selectValue(final String xpath, Node node) throws YAXPathExpressionException
{
XPathExpression xPathExpression = compileXPathExpression(xpath);
try
{
return (String) xPathExpression.evaluate(node, XPathConstants.STRING);
}
catch (XPathExpressionException e)
{
throw new YAXPathExpressionException(xpath, "Error while evaluating xpath expression: " + xpath, e);
}
}
public static List<Node> select(XPath xp, String xpath, Node node) throws XPathExpressionException
{
NodeList nl = (NodeList) xp.evaluate(xpath, node, XPathConstants.NODESET);
List<Node> nodeList = new LinkedList<>();
for (int i = 0; i < nl.getLength(); i++)
{
nodeList.add(nl.item(i));
}
return nodeList;
}
public static List<Node> select(XPathExpression compiledXPath, Node node) throws XPathExpressionException
{
NodeList nl;
nl = (NodeList) compiledXPath.evaluate(node, XPathConstants.NODESET);
List<Node> nodeList = new LinkedList<>();
for (int i = 0; i < nl.getLength(); i++)
{
nodeList.add(nl.item(i));
}
return nodeList;
}
public static List<Node> select(String xpath, Node node) throws YAXPathExpressionException
{
try
{
return select(compileXPathExpression(xpath), node);
}
catch (XPathExpressionException e)
{
throw new YAXPathExpressionException(xpath, "Error while evaluating XPATH expression: " + xpath, e);
}
}
public static List<String> selectValues(String xpath, Node node) throws YAXPathExpressionException
{
List<String> result = new LinkedList<>();
List<Node> list = select(xpath, node);
for (Node n : list)
{
result.add(n.getTextContent());
}
return result;
}
private static XPathExpression compileXPathExpression(final String xpath) throws YAXPathExpressionException
{
XPath xPath = createXPath();
XPathExpression compiledXPath;
try
{
compiledXPath = xPath.compile(xpath);
}
catch (XPathExpressionException t)
{
throw new YAXPathExpressionException(xpath, "Error parsing XPATH expression", t);
}
return compiledXPath;
}
}