如何使用java为XML中的节点生成Xpath? [英] How to generate Xpath for a node in XML using java?

查看:25
本文介绍了如何使用java为XML中的节点生成Xpath?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一段代码可以为节点生成 xpath.但它不会创建它的数组结构.例如,如果一个元素有两个同名的元素,我需要提供索引以适当地指向它们.其插图如下.

I have a piece of code to generate xpath for a node. But it doesn't create array structure of it. For example, if an element has two elements with same name, I need to provide index to point to them appropriately. An illustration of it is below.

<abc>
  <def>
     </hij>
  </def>
  <def>
     </lmn>
  </def>
</abc>

现在,要为 hij 获取 xpath,我需要这样的东西:

Now, to get xpath for hij , I would need something like this:

//abc[1]/def[1]/hij

要为 lmn 获取 xpath,我需要这样的东西:

To get xpath for lmn , I would need something like this:

//abc[1]/def[2]/lmn

我有一段代码,它只会给我 //abc/def/hij//abc/def/lmn

I have a piece of code which will simply give me //abc/def/hij and //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;
    }

有人可以帮我用这个附加数组结构吗?

Can someone help me to append array structure with this?

推荐答案

我无法修复问题中的代码,因为它不完整,例如地图定义在哪里?另请参阅有关格式错误的输入的其他答案.

I'm unable to fix your code in the question as it is not complete, for example where is map defined? Also see other answer about your malformed input.

假设 hij 和 lmn 应该是短标签,这里有一个完整的解决方案.

Making the assumption that hij and lmn should have been short tags, here is a complete solution.

  • 我使用了使用 getParentNode() 在树上导航的方法.
  • 我已经包含了 XPath 测试来检查生成的表达式是否返回相同的节点
  • 扩展输入以在同一级别包含不同名称的元素.

代码

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]

这篇关于如何使用java为XML中的节点生成Xpath?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆