当前位置: 首页 > 面试题库 >

如何使用Xpath检索XML树的一个接一个的节点?

呼延俊风
2023-03-14
问题内容

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

给出以下代码:

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

如果我想找到first回合1和门1 的节点,请在此处:

<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;

如果我想要second第一回合和第一回合的节点,则:

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

但如何使用一个循环,因为我不知道多少我做Value- nodes我的,这意味着我怎么能这样使用一个循环,其中每个迭代我取回3(我的意思是xVal1xVal2pVal值)的值更值节点!?

要求这样做的原因是:

  1. 我不知道Round我有多少

  2. 我不知道Value我有多少

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

谢谢 。


问题答案:

选项1- 遍历文档中的所有Value元素。仅需要进行一次评估,但很难知道该值属于哪个回合或门元素。

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

选项2-分别 遍历每个Round,Door和Value元素。需要更多评估,但上下文很容易理解。如果需要索引,则很容易在循环中添加一个计数器。

// 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- 根据您的要求将以上内容组合在一起

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



 类似资料:
  • 我最近正在评估图形数据库或任何其他数据库的一个特定要求: 通过一个查询中节点的直接子节点及其所有直接和间接子节点的聚合属性检索每个节点的前n个子节点的能力。结果应返回正确的层次结构。 实例 < code >每个节点都有一个属性,即它有多少个直接子节点。并且该树不超过8层。假设我想运行整个树的查询,通过每个级别的所有节点,它的前2个子节点有最多的直接和间接子节点。它将为我们提供以下信息: 我想知道是

  • 问题内容: 我有一个xform文档 我想使用xpath和jdom从xform中选择数据元素 似乎工作正常,并选择title元素,但 不选择模型元素。我想这与名称空间有关。 问题答案: 一些东西。您 确实 应该使用JDOM 2.0.x …(最新版本2.0.5)。2.0.x版本中的XPath API远远优于JDOM 1.x中的XPath API:请参阅https://github.com/hunter

  • 我正在研究一种方法,使用二叉搜索树获取前一个节点。现在我想我明白了,但是我正在努力处理我的if语句。 说明如下:getPrevNode(BSTNode)方法应该在树中找到参数前面的节点。这是我正在使用的算法。 如果节点有左子节点,向下移动左子树以获得最大节点 •否则,如果节点有父节点,我们需要按如下方式向上移动树: •如果节点是正确的子节点,则返回其父节点 •如果节点是左边的子节点,则向上移动树,

  • 问题内容: 我有一个像这样开始的XML文件: 我将不得不打开许多这些文件。它们中的每一个都有不同的名称空间,但一次只能有一个名称空间(我永远不会在一个xml文件中找到两个定义的名称空间)。 使用XPath,我希望有一种自动的方法将给定的名称空间添加到名称空间管理器中。到目前为止,我只能通过解析xml文件来获取名称空间,但是我有一个XPathNavigator实例,并且它应该具有一种不错且干净的方式

  • 问题内容: 例如 根= NodeToInsert可能是 输出应为: 问题答案: 如果事实证明我只是为您做功课,我会感到非常恼火。 结果将是:

  • 作为前言,我对JavaFX编程非常陌生。(我们上学期在我的一堂课上介绍了JavaFX,在过去的一个月左右的时间里,我一直在努力用JavaFX制作一个简单的游戏。 我遇到的一个问题是试图检测一个StackPane中的窗格与另一个StackPane中的窗格的冲突。具体来说,我在Game类中有一个“Player”节点(“Player”扩展了抽象的“Sprite ”,后者扩展了StackPane)以及一些