如何使用java为XML中的节点生成Xpath?
我有一段代码为节点生成xpath。但它并没有创建它的数组结构。例如,如果一个元素有两个同名的元素,我需要提供相应的索引来指向它们。下面是一个例子如何使用java为XML中的节点生成Xpath?,java,xml,xpath,Java,Xml,Xpath,我有一段代码为节点生成xpath。但它并没有创建它的数组结构。例如,如果一个元素有两个同名的元素,我需要提供相应的索引来指向它们。下面是一个例子 <abc> <def> </hij> </def> <def> </lmn> </def> </abc> 要获取lmn的xpath,我需要如下内容: //abc[1]/def[1]/hij //abc[1]/def[2
<abc>
<def>
</hij>
</def>
<def>
</lmn>
</def>
</abc>
要获取lmn
的xpath,我需要如下内容:
//abc[1]/def[1]/hij
//abc[1]/def[2]/lmn
我有一段代码,它只会给我//abc/def/hij
和//abc/def/lmn
private String getXPath(Node root, String elementName)
{
for (int i = 0; i < root.getChildNodes().getLength(); i++)
{
Node node = root.getChildNodes().item(i);
if (node instanceof Element)
{
if (node.getNodeName().equals(elementName))
{
return "\\" + node.getNodeName();
}
else if (node.getChildNodes().getLength() > 0)
{
if(map.containsKey(node.getNodeName()))
map.put(node.getNodeName(), map.get(node.getNodeName())+1);
else
map.put(node.getNodeName(), 1);
this.xpath = getXPath(node, elementName);
if (this.xpath != null){
return "\\" + node.getNodeName() +"["+map.get(node.getNodeName())+"]"+ this.xpath;
}
}
}
}
return null;
}
私有字符串getXPath(节点根,字符串elementName)
{
对于(int i=0;i
<abc>
<def>
</hij>
</def>
<def>
</lmn>
</def>
</abc>
在这里。你快关门了
</hij>
及
没有打开它们。如果您在abc之前打开它们,则不能在abc内部关闭它们。
基本上:你不能缠绕它们。
开一,开二,关二,关一。永远不要用另一种方式
这可能会导致您的错误我无法修复问题中的代码,因为它不完整,例如地图定义在哪里?另请参阅有关错误输入的其他答案 假设hij和lmn应该是短标签,下面是一个完整的解决方案
- 我使用了使用getParentNode()向上导航树的方法李>
- 我已经包含了XPath测试来检查生成的表达式是否返回相同的节点
- 扩展输入,在同一级别包含不同名称的元素
</lmn>
public class Test {
private static String getXPath(Node root) {
Node current = root;
String output = "";
while (current.getParentNode() != null) {
Node parent = current.getParentNode();
if (parent != null && parent.getChildNodes().getLength() > 1) {
int nthChild = 1;
Node siblingSearch = current;
while ((siblingSearch = siblingSearch.getPreviousSibling()) != null) {
// only count siblings of same type
if (siblingSearch.getNodeName().equals(current.getNodeName())) {
nthChild++;
}
}
output = "/" + current.getNodeName() + "[" + nthChild + "]" + output;
} else {
output = "/" + current.getNodeName() + output;
}
current = current.getParentNode();
}
return output;
}
public static void main(String[] args) throws Exception {
String input = "<abc><def><hij /></def><def><lmn /><xyz /><lmn /></def></abc>";
Document root = DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(new InputSource(new StringReader(input)));
test(root.getDocumentElement(), root);
}
private static void test(Node node, Document doc) throws Exception {
String expression = getXPath(node);
Node result = (Node) XPathFactory.newInstance().newXPath()
.compile(expression).evaluate(doc, XPathConstants.NODE);
if (result == node) {
System.out.println("Test OK : " + expression);
} else {
System.out.println("Test Fail: " + expression);
}
for (int i = 0; i < node.getChildNodes().getLength(); i++) {
test(node.getChildNodes().item(i), doc);
}
}
}
Test OK : /abc
Test OK : /abc/def[1]
Test OK : /abc/def[1]/hij
Test OK : /abc/def[2]
Test OK : /abc/def[2]/lmn[1]
Test OK : /abc/def[2]/xyz[1]
Test OK : /abc/def[2]/lmn[2]