
core.apiCore.helpers.XmlHelper Maven / Gradle / Ivy
package core.apiCore.helpers;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
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 org.apache.commons.lang.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.XML;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
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 core.helpers.Helper;
import core.support.logger.TestLog;
import core.support.objects.KeyValue;
import core.support.objects.ServiceObject;
public class XmlHelper {
/**
* Convert a contents of a Document to a String
*
* @param doc
* @return String
*/
public static String convertDocumentToString(Document doc) {
try {
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(doc), new StreamResult(sw));
return sw.toString();
} catch (IllegalArgumentException | TransformerException ex) {
throw new RuntimeException("Error converting to String", ex);
}
}
/**
* Convert a String in XML format to a Document
*
* @param xmlStr
* @return Document
*/
public static Document convertXmlStringToDocument(String xmlStr) {
Document doc = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(new InputSource(new StringReader(xmlStr)));
doc.getDocumentElement().normalize();
} catch (Exception e) {
e.printStackTrace();
Helper.assertFalse(e.getMessage());
}
return doc;
}
/**
* Convert contents of an XML file to a string
*
* @param filePath
* @return String
*/
public static String convertXmlFileToString(Path filePath) {
Document document = readFile(filePath.toString());
return convertDocumentToString(document);
}
/**
* Read a XML file And get a Document retrying And catching interruptions from
* other threads.
*
* @param inputFilePath
* @return Document
*/
public synchronized static Document readFile(String inputFilePath) {
Document doc = null;
int retry = 3;
do {
try {
retry--;
String inputFileContents = new String(Files.readAllBytes(Paths.get(inputFilePath)));
inputFileContents = DataHelper.replaceParameters(inputFileContents);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(new InputSource(new StringReader(inputFileContents)));
doc.getDocumentElement().normalize();
} catch (Exception ex) {
Thread.interrupted();
}
} while (doc == null && retry > 0);
return doc;
}
/**
* Get text value of the node specified by xpath
*
* @param xpathString
* @param xmlString
* @return String
*/
public static String getNodeValue(String xpathString, String xmlString) {
return getNodeList(xpathString, xmlString).item(0).getTextContent();
}
/**
* Get text value of the node specified by xpath
*
* @param xpathString
* @param xmlString
* @return String
*/
public static NodeList getNodeList(String xpathString, String xmlString) {
try {
Document doc = convertXmlStringToDocument(xmlString);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xpath.evaluate(xpathString, doc, XPathConstants.NODESET);
if (nodeList == null || nodeList.getLength() == 0) {
TestLog.ConsoleLog("No node found for xpath value: {0}", xpathString);
} else {
return nodeList;
}
} catch (XPathExpressionException ex) {
TestLog.logWarning("Exception encountered for xpath value: " + xpathString, ex);
}
return null;
}
/**
* converts json string to xml and gets xpath value from it
*
* @param json
* @param xpath
* @return result list as string separated by ","
*/
public static String getXpathValueFromJson(String json, String xpath) {
String value = StringUtils.EMPTY;
// convert xml string to json string
String xml = jsonToXml(json);
// get xpath value form xml string
value = getXpathFromXml(xml, xpath);
return value;
}
/**
* get xpath value form xml string test out xpath values at:
* https://www.freeformatter.com/xpath-tester.html#ad-output
*
* @param xml
* @param xpath
* @return result list as string separated by ","
*/
public static String getXpathFromXml(String xml, String xpath) {
List valueList = new ArrayList();
// convert xml string to doc
Document doc = convertXmlStringToDocument(xml);
XPathFactory xPathFactory = XPathFactory.newInstance();
// Create XPath object from XPathFactory
XPath xpathObject = xPathFactory.newXPath();
try {
// Compile the XPath expression for getting all brands
XPathExpression xPathEnvelopeExpr = xpathObject.compile(xpath);
Object result = xPathEnvelopeExpr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
valueList = new ArrayList();
for (int i = 0; i < nodes.getLength(); i++) {
valueList.add(nodes.item(i).getTextContent());
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return DataHelper.listToString(valueList);
}
/**
* convert json string to xml string
*
* @param json
* @return
*/
public static String jsonToXml(String json) {
String xml = StringUtils.EMPTY;
try {
JSONObject jsonObject = new JSONObject(json);
xml = XML.toString(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
return xml;
}
/**
* if request body is empty, return xml template string if request body contains
* xml tag, replace tag with value eg. "soi:EquipmentID:1:equip_<@_TIME_17>"
*
* @param serviceObject
* @return
*/
public static String getRequestBodyFromXmlTemplate(ServiceObject serviceObject) {
Path templatePath = DataHelper.getTemplateFilePath(serviceObject.getTemplateFile());
String xmlFileValue = convertXmlFileToString(templatePath);
xmlFileValue = DataHelper.replaceParameters(xmlFileValue);
if (serviceObject.getRequestBody().isEmpty()) {
return xmlFileValue;
} else {
String xmlString = DataHelper.getServiceObjectTemplateString(serviceObject);
return XmlHelper.replaceRequestTagValues(serviceObject.getRequestBody(), xmlString);
}
}
/**
* replace tag value in xml string at index
*
* @param position: starts at 1
* @param tag
* @param value
* @return
*/
public static String replaceTagValue(String xml, String tag, String value, int position) {
xml = replaceGroup("<" + tag + ">(.*?)<\\/" + tag + ">", xml, 1, position, value);
return xml;
}
/**
* replace tag value in xml for all occurrences
*
* @param xml
* @param tag
* @param value
* @return
*/
public static String replaceTagValue(String xml, String tag, String value) {
xml = xml.replaceAll("<" + tag + ">(.*?)<\\/" + tag + ">", "<" + tag + ">" + value + "" + tag + ">");
return xml;
}
/**
* generic replace value using regex using index
*
* @param regex
* @param source
* @param groupToReplace
* @param groupOccurrence
* @param replacement
* @return
*/
public static String replaceGroup(String regex, String source, int groupToReplace, int groupOccurrence,
String replacement) {
if (groupOccurrence == 0)
Helper.assertFalse("position starts at 1");
Matcher m = Pattern.compile(regex).matcher(source);
for (int i = 0; i < groupOccurrence; i++)
if (!m.find())
Helper.assertFalse("pattern not found for: " + regex + " at source: " + source);
return new StringBuilder(source).replace(m.start(groupToReplace), m.end(groupToReplace), replacement)
.toString();
}
/**
* replaces request header tag values eg. "soi:EquipmentID:1:<@_TIME_16>" tag:
* soi:EquipmentID, position: 1, value: <@_TIME_16>
*
* @param serviceObject
* @return
*/
public static String replaceRequestTagValues(String requestbody, String xmlString) {
Helper.assertTrue("xml string is empty", !xmlString.isEmpty());
// replace parameters
xmlString = DataHelper.replaceParameters(xmlString);
// if request is valid xml, do not update. only key value pair
if (isValidXmlString(requestbody)) {
return requestbody;
}
// get key value mapping of header parameters
List keywords = DataHelper.getValidationMap(requestbody);
for (KeyValue keyword : keywords) {
if(keyword.value.toString().isEmpty()) continue;
if(keyword.position.isEmpty())
keyword.position = "1";
xmlString = replaceTagValue(xmlString, keyword.key, keyword.value.toString(),
Integer.valueOf(keyword.position));
}
return xmlString;
}
/**
* get first matching tag value
*
* @param requestBody
* @param tag
* @return
*/
public static String getXmlTagValue(String value, String tag) {
return getXmlTagValue(value, tag, 1);
}
/**
* get tag value
*
* @param source
* @param tag
* @param position: starts at 1
* @return
*/
public static String getXmlTagValue(String source, String tag, int position) {
List values = new ArrayList();
try {
if(tag.equals("."))
return source;
String patternString = "<" + tag + ">(.*?)<\\/" + tag + ">";
final Pattern pattern = Pattern.compile(patternString);
final Matcher matcher = pattern.matcher(source);
while (matcher.find()) {
values.add(matcher.group(1));
}
} catch (Exception e) {
e.getMessage();
}
if (position == 0)
Helper.assertFalse("position starts at 1. your position: " + position + ".");
if (values.isEmpty())
Helper.assertFalse(
"tag value: " + tag + " at position: " + position + " was not found at xml: \n" + source + " \n\n");
if (position > values.size())
Helper.assertFalse("position is greater than response size. position: " + position + ". response size: "
+ values.size() + ". values: " + Arrays.toString(values.toArray()));
return values.get(position - 1);
}
/**
* return true if file is xml file
*
* @param filename
* @return
*/
public static boolean isXmlFile(String filename) {
if (filename.toLowerCase().endsWith("xml"))
return true;
return false;
}
/**
* validates if xml string is valid xml
*
* @param xmlString
* @return
*/
public static boolean isValidXmlString(String xmlString) {
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setValidating(false);
dbFactory.setSchema(null);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
dBuilder.setErrorHandler(new ErrorHandler() {
@Override
public void warning(SAXParseException exception) throws SAXException {
}
@Override
public void error(SAXParseException exception) throws SAXException {
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
}
});
dBuilder.parse(new InputSource(new StringReader(xmlString)));
return true;
} catch (Exception e) {
return false;
}
}
public static String prettyFormat(String input, int indent) {
try {
Source xmlInput = new StreamSource(new StringReader(input));
StringWriter stringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(stringWriter);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", indent);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(xmlInput, xmlOutput);
return xmlOutput.getWriter().toString();
} catch (Exception e) {
throw new RuntimeException(e); // simple exception handling, please review it
}
}
/**
* remove namespaces from xml
* gets namespace tags in list and removes them
* @param xmlString
* @return
*/
public static String removeXmlNameSpace(String xmlString) {
Document doc = convertXmlStringToDocument(xmlString);
Document updateDoc = cleanNameSpace(doc);
String xmlNoNameSpace = convertDocumentToString(updateDoc);
return xmlNoNameSpace;
}
/**
* remove namespaces from xml
* gets namespace tags in list and removes them
* @param doc
* @return
*/
public static Document cleanNameSpace(Document doc) {
NodeList list = doc.getChildNodes();
List namespaces = new ArrayList();
for (int i = 0; i < list.getLength(); i++) {
removeNamSpace(list.item(i), "", namespaces);
}
return doc;
}
/**
* remove namespaces from xml
* gets namespace tags in list and removes them
* @param node
* @param nameSpaceURI
* @param namespaces
*/
private static void removeNamSpace(Node node, String nameSpaceURI, List namespaces) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Document doc = node.getOwnerDocument();
NamedNodeMap map = node.getAttributes();
Node n;
// get list of namespace tags
namespaces = getXmlNamespaceTags(map, namespaces);
// removes namespaces in list from xml
List nodeList = new ArrayList();
for (int i = 0; i < map.getLength(); i++) {
n = map.item(i);
// add nodes with namespace in local name to list to be removed
if (n.getNodeName() != null) {
if (n.getNodeName().contains("xmlns")) {
nodeList.add(n);
continue;
}
for (String namespace : namespaces) {
if (n.getNodeName().contains(namespace + ":")) {
nodeList.add(n);
break;
}
}
}
}
for (int i = 0; i < nodeList.size(); i++) {
map.removeNamedItemNS(nodeList.get(i).getNamespaceURI(), nodeList.get(i).getLocalName());
}
doc.renameNode(node, nameSpaceURI, node.getLocalName());
}
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
removeNamSpace(list.item(i), nameSpaceURI, namespaces);
}
}
/**
* get list of xml namespace tags
* @param map
* @return
*/
private static List getXmlNamespaceTags(NamedNodeMap map, List namespaces) {
Node n;
// get list of namespace tags
for (int i = 0; i < map.getLength(); i++) {
n = map.item(i);
// get namespace tags
if (n.getNodeName() != null && n.getNodeName().contains("xmlns")) {
String[] namespaceArray = n.getNodeName().split(":");
if (namespaceArray.length == 2)
namespaces.add(namespaceArray[1]);
}
}
return namespaces;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy