如何使用 Xpath 检索 XML 树的节点后的节点?

How to retrieve node after node of XML tree using Xpath?(如何使用 Xpath 检索 XML 树的节点后的节点?)
本文介绍了如何使用 Xpath 检索 XML 树的节点后的节点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

首先,我必须说,我发现 Xpath 是一个非常好的解析器,并且在与其他解析器进行比较时,我认为它非常强大.

First, I must say that I find Xpath as a very nice parser , and I guess pretty powerful when comparing it to other parsers .

给定以下代码:

  DocumentBuilderFactory domFactory = 
  DocumentBuilderFactory.newInstance();
  domFactory.setNamespaceAware(true); 
  DocumentBuilder builder = domFactory.newDocumentBuilder();
  Document doc = builder.parse("input.xml");
  XPath xpath = XPathFactory.newInstance().newXPath();

如果我想找到第 1 轮的 first 节点 &1号门,这里:

If I wanted to find the first node of Round 1 & Door 1 , here :

<Game>
    <Round>
        <roundNumber>1</roundNumber>
        <Door>
            <doorName>abd11</doorName>
            <Value>
                <xVal1>0</xVal1>
                <xVal2>25</xVal2>
                <pVal>0.31</pVal>
            </Value>
            <Value>
                <xVal1>25</xVal1>
                <xVal2>50</xVal2>
                <pVal>0.04</pVal>
            </Value>
            <Value>
                <xVal1>50</xVal1>
                <xVal2>75</xVal2>
                <pVal>0.19</pVal>
            </Value>
            <Value>
                <xVal1>75</xVal1>
                <xVal2>100</xVal2>
                <pVal>0.46</pVal>
            </Value>
        </Door>
        <Door>
            <doorName>vvv1133</doorName>
            <Value>
                <xVal1>60</xVal1>
                <xVal2>62</xVal2>
                <pVal>1.0</pVal>
            </Value>
        </Door>
    </Round>
    <Round>
        <roundNumber>2</roundNumber>
        <Door>
            <doorName>eee</doorName>
            <Value>
                <xVal1>0</xVal1>
                <xVal2>-25</xVal2>
                <pVal>0.31</pVal>
            </Value>
            <Value>
                <xVal1>-25</xVal1>
                <xVal2>-50</xVal2>
                <pVal>0.04</pVal>
            </Value>
            <Value>
                <xVal1>-50</xVal1>
                <xVal2>-75</xVal2>
                <pVal>0.19</pVal>
            </Value>
            <Value>
                <xVal1>-75</xVal1>
                <xVal2>-100</xVal2>
                <pVal>0.46</pVal>
            </Value>
        </Door>
        <Door>
            <doorName>cc</doorName>
            <Value>
                <xVal1>-60</xVal1>
                <xVal2>-62</xVal2>
                <pVal>0.3</pVal>
            </Value>
            <Value>
                <xVal1>-70</xVal1>
                <xVal2>-78</xVal2>
                <pVal>0.7</pVal>
            </Value>
        </Door>
    </Round>
</Game>

我会这样做的:

 XPathExpression expr = xpath.compile("//Round[1]/Door[1]/Value[1]/*/text()");      
  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  NodeList nodes = (NodeList) result;

如果我想要第 1 轮的 second 节点 &那么门1:

and if I wanted the second node of Round 1 & Door 1 then :

XPathExpression expr = xpath.compile("//Round[1]/Door[1]/Value[2]/*/text()");  

但是我如何使用循环来做到这一点,因为我不知道我有多少 Value-nodes ,这意味着我如何使用循环来做到这一点,每次迭代我都会检索 3(我的意思是 xVal1xVal2pVal 值)更多值节点的值!?

but how do I do this using a loop , since I don't know how much Value-nodes I have , meaning how can I do this using a loop , where each iteration I retrieve 3 (I mean the xVal1 , xVal2 and pVal values ) more values of a Value node !?

要求这样做的原因是:

  1. 我不知道我有多少Round-s

我不知道我有多少Value-s

我不想每次都声明一个新的XPathExpression

I don't want to declare every time a new XPathExpression

谢谢.

推荐答案

选项 1 - 遍历文档中的所有 Value 元素.只需要一次评估,但很难知道该值属于哪个圆形或门元素.

Option 1 - Iterate over all Value elements in the document. Only one evaluation required, but difficult to know which Round or Door element the Value belongs to.

NodeList result = (NodeList) xpath.evaluate("//Round/Door/Value/*/text()", doc, XPathConstants.NODESET);

选项 2 - 分别迭代每个 Round、Door 和 Value 元素.需要更多评估,但上下文很容易知道.如果需要索引,很容易在循环中添加一个计数器.

Option 2 - Iterate over each Round, Door and Value elements separately. Requires more evaluations but the context is easily known. If index is required, it is easy to add a counter to the loops.

// Get all rounds and iterate over them
NodeList rounds = (NodeList) xpath.evaluate("//Round", doc, XPathConstants.NODESET);
for (Node round : rounds) {
  // Get all doors and iterate over them
  NodeList doors = (NodeList) xpath.evaluate("Door", round, XPathConstants.NODESET);
  for (Node door : doors) {
    // Get all values and iterate over them
    NodeList values = (NodeList) xpath.evaluate("Value/*/text()", door, XPathConstants.NODESET);
    for (Node value : values) {
      // Do something
    }
  }
}

选项 3 - 根据您的要求将上述方法组合起来

Option 3 - Do some combination of the above depending on your requirements

请注意,我删除了表达式编译步骤以缩短示例.应该重新添加它以提高性能.

Note that I've removed the expression compilation step to shorten the example. It should be re-added to improve performance.

这篇关于如何使用 Xpath 检索 XML 树的节点后的节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How to send data to COM PORT using JAVA?(如何使用 JAVA 向 COM PORT 发送数据?)
How to make a report page direction to change to quot;rtlquot;?(如何使报表页面方向更改为“rtl?)
Use cyrillic .properties file in eclipse project(在 Eclipse 项目中使用西里尔文 .properties 文件)
Is there any way to detect an RTL language in Java?(有没有办法在 Java 中检测 RTL 语言?)
How to load resource bundle messages from DB in Java?(如何在 Java 中从 DB 加载资源包消息?)
How do I change the default locale settings in Java to make them consistent?(如何更改 Java 中的默认语言环境设置以使其保持一致?)