У меня есть XML-документ со следующей структурой:
<root>
<a>
<bd>
<cd>
<aa/>
<bb/>
<aa/>
</cd>
</bd>
</a>
<a>
<bd>
<cd>
<aa/>
<bb/>
<aa/>
</cd>
</bd>
</a>
<tt>
<at/>
<bt/>
</tt>
</root>
Я использую рекурсивную функцию, которая принимает объект-узел в качестве параметра. Я хочу получить xpath каждого узла в индексированном выражении XPath, например root/a[1]/bd[0]/aa[2]
. Я использую парсер DOM и вызываю эту функцию из другой рекурсивной функции.
private static String getXPath(Node test_tempNode) {
if (test_tempNode == null
|| test_tempNode.getNodeType() != Node.ELEMENT_NODE) {
return "";
}
return getXPath(test_tempNode.getParentNode()) + "/"
+ test_tempNode.getNodeName();
}
Ваш код, похоже, работает, за исключением того, что он не добавляет индекс; Поэтому я предполагаю, что все, что вам нужно сделать, - это найти позицию текущего узла в родительском дочернем списке и добавить его в xpath
private static String getXPath(Node test_tempNode) {
if (test_tempNode == null
|| test_tempNode.getNodeType() != Node.ELEMENT_NODE) {
return "";
}
//find index of the test_tempNode node in parent "list"
Node parent = test_tempNode.getParentNode();
NodeList childNodes = parent.getChildNodes();
int index = 0;
int found = 0;
for (int i = 0; i < childNodes.getLength(); i++) {
Node current = childNodes.item(i);
if (current.getNodeName().equals(test_tempNode.getNodeName())) {
if (current == test_tempNode) {
found = index;
}
index++;
}
}
String strIdx = "[" + found + "]";
if(index == 1){
strIdx = "";
}
return getXPath(test_tempNode.getParentNode()) + "/"
+ test_tempNode.getNodeName() + strIdx;
}
Это должно печатать уникальный путь для каждого узла, при необходимости добавляя индекс.
private void printXPaths(Node node, OutputStream stream, String current, Map<String, int> occurences)
{
if (node.getNodeType() != Node.ELEMENT_NODE) {
return;
}
String nodePath = current + "/" + node.getNodeName();
if(occurences.contains(nodePath)) {
int occurrencesCount = occurences[nodePath];
nodePath += "[" + occurrencesCount + "]";
occurences[nodePath] = occurrencesCount + 1;
} else {
occurences[nodePath] = 1;
}
stream.println(nodePath);
NodeList children = node.getChildNodes();
for(int i=0; i<children.getLength(); i++) {
printXPaths(children.item(i), stream, nodePath, occurences);
}
}
public void printXPaths(Document doc, OutputStream stream) {
printXPaths(doc.getDocumentElement(), stream, "", new HashMap<String, int>());
}
Таким образом, первый указатель отобразит /root/tag, а второй покажет /root/tag [1] и так далее. Надеюсь, это поможет.
<root/>
должны быть</root>
. Пожалуйста, отредактируйте вопрос и исправьте XML, чтобы он был правильно сформирован.