获取 XML 标签的 XPath [英] Get XPath of XML Tag

查看:27
本文介绍了获取 XML 标签的 XPath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个像下面这样的 XML 文档:

If I have an XML document like below:

<foo>
   <foo1>Foo Test 1</foo1>
   <foo2>
       <another1>
           <test10>This is a duplicate</test10>
       </another1>
   </foo2>
   <foo2>
       <another1>
           <test1>Foo Test 2</test1>
       </another1>
   </foo2>
   <foo3>Foo Test 3</foo3>
   <foo4>Foo Test 4</foo4>
</foo>

例如,我如何获得 的 XPath?所以输出应该是这样的:foo/foo2[2]/another1/test1

How do I get the XPath of <test1> for example? So the output should be something like: foo/foo2[2]/another1/test1

我猜代码应该是这样的:

I'm guessing the code would look something like this:

public String getXPath(Document document, String xmlTag) {
   String xpath = "";
   ...
   //Get the node from xmlTag
   //Get the xpath using the node
   return xpath;
}

假设 String XPathVar = getXPath(document, "");.我需要取回一个可以在以下代码中工作的绝对 xpath:

Let's say String XPathVar = getXPath(document, "<test1>");. I need to get back an absolute xpath that will work in the following code:

XPath xpath = XPathFactory.newInstance().newXPath(); 
XPathExpression xpr = xpath.compile(XPathVar); 
xpr.evaluate(Document, XPathConstants.STRING); 

但它不能像 //test1 这样的快捷方式,因为它也将用于元数据目的.

But it can't be a shortcut like //test1 because it will also be used for meta data purposes.

通过以下方式打印结果时:

When printing the result out via:

System.out.println(xpr.evaluate(Document, XPathConstants.STRING));

我应该得到节点的值.所以如果 XPathVar = foo/foo2[2]/another1/test1 那么我应该回来:

I should get the node's value. So if XPathVar = foo/foo2[2]/another1/test1 then I should get back:

Foo Test 2 而不是 这是重复的

推荐答案

获取"xpath 的方式与获取"sql 的方式不同.

You don't 'get' an xpath in the same way you don't 'get' sql.

xpath 是您根据对 xml 文档或架构的理解编写的查询,就像 sql 是您根据对数据库架构的理解编写的查询一样 - 您不会获得"其中任何一个.

An xpath is a query you write based on your understanding of an xml document or schema, just as sql is a query you write based on your understanding of a database schema - you don't 'get' either of them.

我可以简单地通过从给定节点返回节点来从 DOM 生成 xpath 语句,尽管这样做足够通用,考虑到每个节点上的属性值,会使生成的代码几乎无用.例如(带有警告,这将找到具有给定名称的第一个节点,xpath 远不止于此,您也可以只使用 xpath //foo2):

I would be possible to generate xpath statements from the DOM simply by walking back up the nodes from a given node, though to do this generically enough, taking into account attribute values on each node, would make the resulting code next to useless. For example (which comes with a warning that this will find the first node that has a given name, xpath is much more that this and you may as well just use the xpath //foo2):

import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class XPathExample 
{
  private static 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)
        {
          String xpath = getXPath(node, elementName);
          if (xpath != null)
          {
            return "/" + node.getNodeName() + xpath;
          }
        }
      }
    }

    return null;
  }

  private static String getXPath(Document document, String elementName)
  {
    return document.getDocumentElement().getNodeName() + getXPath(document.getDocumentElement(), elementName);
  }

  public static void main(String[] args) 
  {
    try 
    {
      Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
        new ByteArrayInputStream(
          ("<foo><foo1>Foo Test 1</foo1><foo2><another1><test1>Foo Test 2</test1></another1></foo2><foo3>Foo Test 3</foo3><foo4>Foo Test 4</foo4></foo>").getBytes()
        )
      );

      String xpath = "/" + getXPath(document, "test1");
      System.out.println(xpath);        

      Node node1 = (Node)XPathFactory.newInstance().newXPath().compile(xpath).evaluate(document, XPathConstants.NODE);
      Node node2 = (Node)XPathFactory.newInstance().newXPath().compile("//test1").evaluate(document, XPathConstants.NODE);

      //This evaluates to true, hence you may as well just use the xpath //test1.
      System.out.println(node1.equals(node2));
    }
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
}

同样,您可以编写一个 XML 转换,将一个 xml 文档转换为一系列 xpath 语句,但这种转换会比首先编写 xpath 更复杂,因此在很大程度上毫无意义.

Likewise you could write an XML transformation that turned an xml document into a series of xpath statements but this transformation would be more complicated that writing the xpath in the first place and so largely pointless.

这篇关于获取 XML 标签的 XPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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