fork download
  1. import java.io.ByteArrayInputStream;
  2. import javax.xml.parsers.*;
  3. import org.w3c.dom.Document;
  4. import org.w3c.dom.Element;
  5. import org.w3c.dom.Node;
  6. import javax.xml.xpath.*;
  7. import java.io.*;
  8. import org.xml.sax.*;
  9.  
  10. public class Main{
  11.  
  12. public static void main(String[] args) {
  13. try
  14. {
  15. String xmlStr ="<foo><foo1>Foo Test 1</foo1><foo2>hello</foo2><foo2/><foo2><another1 /><another1><test1>Foo Test 2</test1></another1></foo2><foo3>Foo Test 3</foo3><foo4>Foo Test 4</foo4></foo>";
  16.  
  17. Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
  18. new ByteArrayInputStream(xmlStr.getBytes())
  19. );
  20.  
  21. String xpath = findXPathInXMLString(89, xmlStr);
  22. System.out.println(xpath);
  23.  
  24. }
  25. catch (Exception e)
  26. {
  27. e.printStackTrace();
  28. }
  29. }
  30.  
  31. public static String findXPathInXMLString(int index, String string) throws XPathExpressionException, SAXException, ParserConfigurationException, IOException {
  32. String xpath;
  33.  
  34. //Step 1. Insert temporary tag in insert location
  35. StringBuilder stringBuilder = new StringBuilder(string);
  36. stringBuilder.insert(index, "<findXPathInXMLStringTemporaryTag />");
  37.  
  38. Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
  39. new ByteArrayInputStream(stringBuilder.toString().getBytes())
  40. );
  41.  
  42. //Step 2. Convert string document to DOM document & Find XPath of temporary tag in DOM document
  43. xpath = getXPath(document, "findXPathInXMLStringTemporaryTag");
  44.  
  45. //Step 3. Cut off last part of the XPath
  46. xpath = xpath.replace("/findXPathInXMLStringTemporaryTag", "");
  47.  
  48. //Step 4. Return the XPath
  49. return xpath;
  50. }
  51.  
  52. private static String getXPath(Document root, String elementName) throws XPathExpressionException
  53. {
  54. XPathExpression expr = XPathFactory.newInstance().newXPath().compile("//"+elementName);
  55. Node node = (Node)expr.evaluate(root, XPathConstants.NODE);
  56.  
  57.  
  58. if(node != null) {
  59. return getXPath(node);
  60. }
  61.  
  62. return null;
  63. }
  64.  
  65. private static String getXPath(Node node) throws XPathExpressionException {
  66. if(node == null || node.getNodeType() != Node.ELEMENT_NODE) {
  67. return "";
  68. }
  69.  
  70. return getXPath(node.getParentNode()) + "/" + node.getNodeName() + getIndex(node);
  71. }
  72.  
  73. private static String getIndex(Node node) throws XPathExpressionException {
  74. XPathExpression expr = XPathFactory.newInstance().newXPath().compile("count(preceding-sibling::*[local-name() = '" + node.getNodeName() + "'])");
  75. int result = (int)(double)(Double)expr.evaluate(node, XPathConstants.NUMBER);
  76.  
  77. if(result == 0){
  78. return "";
  79. }
  80. else {
  81. return "[" + (result + 1) + "]";
  82. }
  83. }
  84.  
  85. }
Success #stdin #stdout 0.1s 246144KB
stdin
Standard input is empty
stdout
/foo/foo2[3]/another1[2]/test1