This is a better solution not depending on anything but pure DOM, and possibly with better performance. It could be improved if there is some kind of publicly accessible table of intern'ed strings in the DOM implementation.
public static String getPathFromRoot(Element e) { Node p = e.getParentNode(); StringBuffer path = new StringBuffer(); try { if (p.getNodeType() == Node.ELEMENT_NODE ) { path.append(getPathFromRoot((Element)p)); } path.append("/"); String prefix = e.getPrefix(); String local = e.getLocalName(); String namespaceUri = e.getNamespaceURI(); path.append(prefix != null ? prefix : ""); path.append(":"); path.append(local); int siblings = 0; for (Node s=e.getPreviousSibling(); s != null; s=s.getPreviousSibling()) { if (s.getNodeType()== Node.ELEMENT_NODE && s.getLocalName().equals(local) && s.getNamespaceURI().equals(namespaceUri)) { ++siblings; } } path.append("["); path.append(1 + siblings); path.append("]"); return path.toString(); } catch (Exception ex) { ex.printStackTrace(System.err); System.exit(-63); } return ""; }