import java.io.ByteArrayInputStream ;
import javax.xml.parsers.* ;
import org.w3c.dom.Document ;
import org.w3c.dom.Element ;
import org.w3c.dom.Node ;
import javax.xml.xpath.* ;
import java.io.* ;
import org.xml.sax.* ;
public class Main{
public static void main
( String [ ] args
) { try
{
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>" ;
Document document
= DocumentBuilderFactory.
newInstance ( ) .
newDocumentBuilder ( ) .
parse ( ) ;
String xpath
= findXPathInXMLString
( 89 , xmlStr
) ;
}
{
e.printStackTrace ( ) ;
}
}
public static String findXPathInXMLString
( int index,
String string
) throws XPathExpressionException, SAXException, ParserConfigurationException,
IOException {
//Step 1. Insert temporary tag in insert location
StringBuilder stringBuilder = new StringBuilder( string) ;
stringBuilder.insert ( index, "<findXPathInXMLStringTemporaryTag />" ) ;
Document document
= DocumentBuilderFactory.
newInstance ( ) .
newDocumentBuilder ( ) .
parse ( ) ;
//Step 2. Convert string document to DOM document & Find XPath of temporary tag in DOM document
xpath = getXPath( document, "findXPathInXMLStringTemporaryTag" ) ;
//Step 3. Cut off last part of the XPath
xpath = xpath.replace ( "/findXPathInXMLStringTemporaryTag" , "" ) ;
//Step 4. Return the XPath
return xpath;
}
{
XPathExpression expr = XPathFactory.newInstance ( ) .newXPath ( ) .compile ( "//" + elementName) ;
Node node = ( Node) expr.evaluate ( root, XPathConstants.NODE ) ;
if ( node != null ) {
return getXPath( node) ;
}
return null ;
}
private static String getXPath
( Node node
) throws XPathExpressionException
{ if ( node == null || node.getNodeType ( ) != Node.ELEMENT_NODE ) {
return "" ;
}
return getXPath( node.getParentNode ( ) ) + "/" + node.getNodeName ( ) + getIndex( node) ;
}
private static String getIndex
( Node node
) throws XPathExpressionException
{ XPathExpression expr = XPathFactory.newInstance ( ) .newXPath ( ) .compile ( "count(preceding-sibling::*[local-name() = '" + node.getNodeName ( ) + "'])" ) ;
int result
= ( int ) ( double ) ( Double ) expr.
evaluate ( node, XPathConstants.
NUMBER ) ;
if ( result == 0 ) {
return "" ;
}
else {
return "[" + ( result + 1 ) + "]" ;
}
}
}
aW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CmltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwppbXBvcnQgb3JnLnczYy5kb20uRG9jdW1lbnQ7CmltcG9ydCBvcmcudzNjLmRvbS5FbGVtZW50OwppbXBvcnQgb3JnLnczYy5kb20uTm9kZTsKaW1wb3J0IGphdmF4LnhtbC54cGF0aC4qOwppbXBvcnQgamF2YS5pby4qOwppbXBvcnQgb3JnLnhtbC5zYXguKjsKCnB1YmxpYyBjbGFzcyBNYWluewoKcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgdHJ5IAogICAgewogICAgICAgIFN0cmluZyB4bWxTdHIgPSI8Zm9vPjxmb28xPkZvbyBUZXN0IDE8L2ZvbzE+PGZvbzI+aGVsbG88L2ZvbzI+PGZvbzIvPjxmb28yPjxhbm90aGVyMSAvPjxhbm90aGVyMT48dGVzdDE+Rm9vIFRlc3QgMjwvdGVzdDE+PC9hbm90aGVyMT48L2ZvbzI+PGZvbzM+Rm9vIFRlc3QgMzwvZm9vMz48Zm9vND5Gb28gVGVzdCA0PC9mb280PjwvZm9vPiI7CiAKICAgICAgRG9jdW1lbnQgZG9jdW1lbnQgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCkubmV3RG9jdW1lbnRCdWlsZGVyKCkucGFyc2UoCiAgICAgICAgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHhtbFN0ci5nZXRCeXRlcygpKQogICAgICApOwogICAgICAKICAgICAgU3RyaW5nIHhwYXRoID0gZmluZFhQYXRoSW5YTUxTdHJpbmcoODksIHhtbFN0cik7CiAgICAgIFN5c3RlbS5vdXQucHJpbnRsbih4cGF0aCk7ICAgICAgICAKCiAgICB9CiAgICBjYXRjaCAoRXhjZXB0aW9uIGUpIAogICAgewogICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwogICAgfSAgICAKfQoKcHVibGljIHN0YXRpYyBTdHJpbmcgZmluZFhQYXRoSW5YTUxTdHJpbmcoaW50IGluZGV4LCBTdHJpbmcgc3RyaW5nKSB0aHJvd3MgWFBhdGhFeHByZXNzaW9uRXhjZXB0aW9uLCBTQVhFeGNlcHRpb24sIFBhcnNlckNvbmZpZ3VyYXRpb25FeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKICAgIFN0cmluZyB4cGF0aDsKCiAgICAvL1N0ZXAgMS4gSW5zZXJ0IHRlbXBvcmFyeSB0YWcgaW4gaW5zZXJ0IGxvY2F0aW9uCiAgICBTdHJpbmdCdWlsZGVyIHN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcihzdHJpbmcpOwogICAgc3RyaW5nQnVpbGRlci5pbnNlcnQoaW5kZXgsICI8ZmluZFhQYXRoSW5YTUxTdHJpbmdUZW1wb3JhcnlUYWcgLz4iKTsKCiAgICBEb2N1bWVudCBkb2N1bWVudCA9IERvY3VtZW50QnVpbGRlckZhY3RvcnkubmV3SW5zdGFuY2UoKS5uZXdEb2N1bWVudEJ1aWxkZXIoKS5wYXJzZSgKICAgICAgICBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc3RyaW5nQnVpbGRlci50b1N0cmluZygpLmdldEJ5dGVzKCkpCiAgICAgICk7CgogICAgLy9TdGVwIDIuIENvbnZlcnQgc3RyaW5nIGRvY3VtZW50IHRvIERPTSBkb2N1bWVudCAmIEZpbmQgWFBhdGggb2YgdGVtcG9yYXJ5IHRhZyBpbiBET00gZG9jdW1lbnQKICAgIHhwYXRoID0gZ2V0WFBhdGgoZG9jdW1lbnQsICJmaW5kWFBhdGhJblhNTFN0cmluZ1RlbXBvcmFyeVRhZyIpOwoKICAgIC8vU3RlcCAzLiBDdXQgb2ZmIGxhc3QgcGFydCBvZiB0aGUgWFBhdGgKICAgIHhwYXRoID0geHBhdGgucmVwbGFjZSgiL2ZpbmRYUGF0aEluWE1MU3RyaW5nVGVtcG9yYXJ5VGFnIiwgIiIpOwoKICAgIC8vU3RlcCA0LiBSZXR1cm4gdGhlIFhQYXRoCiAgICByZXR1cm4geHBhdGg7Cn0KCnByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRYUGF0aChEb2N1bWVudCByb290LCBTdHJpbmcgZWxlbWVudE5hbWUpIHRocm93cyBYUGF0aEV4cHJlc3Npb25FeGNlcHRpb24gCnsKICBYUGF0aEV4cHJlc3Npb24gZXhwciA9IFhQYXRoRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld1hQYXRoKCkuY29tcGlsZSgiLy8iK2VsZW1lbnROYW1lKTsKICBOb2RlIG5vZGUgPSAoTm9kZSlleHByLmV2YWx1YXRlKHJvb3QsIFhQYXRoQ29uc3RhbnRzLk5PREUpOwogIAogIAogIGlmKG5vZGUgIT0gbnVsbCkgewogICAgICByZXR1cm4gZ2V0WFBhdGgobm9kZSk7CiAgfQoKICByZXR1cm4gbnVsbDsKfQoKcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldFhQYXRoKE5vZGUgbm9kZSkgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7CiAgICBpZihub2RlID09IG51bGwgfHwgbm9kZS5nZXROb2RlVHlwZSgpICE9IE5vZGUuRUxFTUVOVF9OT0RFKSB7CiAgICAgICAgcmV0dXJuICIiOwogICAgfQoKICAgIHJldHVybiBnZXRYUGF0aChub2RlLmdldFBhcmVudE5vZGUoKSkgKyAiLyIgKyBub2RlLmdldE5vZGVOYW1lKCkgKyBnZXRJbmRleChub2RlKTsKfQoKcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldEluZGV4KE5vZGUgbm9kZSkgdGhyb3dzIFhQYXRoRXhwcmVzc2lvbkV4Y2VwdGlvbiB7CiAgICBYUGF0aEV4cHJlc3Npb24gZXhwciA9IFhQYXRoRmFjdG9yeS5uZXdJbnN0YW5jZSgpLm5ld1hQYXRoKCkuY29tcGlsZSgiY291bnQocHJlY2VkaW5nLXNpYmxpbmc6OipbbG9jYWwtbmFtZSgpID0gJyIgKyBub2RlLmdldE5vZGVOYW1lKCkgKyAiJ10pIik7CiAgICBpbnQgcmVzdWx0ID0gKGludCkoZG91YmxlKShEb3VibGUpZXhwci5ldmFsdWF0ZShub2RlLCBYUGF0aENvbnN0YW50cy5OVU1CRVIpOwogICAgCiAgICBpZihyZXN1bHQgPT0gMCl7CiAgICAgICAgcmV0dXJuICIiOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgcmV0dXJuICJbIiArIChyZXN1bHQgKyAxKSArICJdIjsKICAgIH0KfQoKfQ==