【问题标题】:Conditions on recursive XPath递归 XPath 的条件
【发布时间】:2016-02-20 23:49:45
【问题描述】:

如何在 XPath 中使用递归 AND 条件选择?

例如,给定这个文档:

<root xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
  <file name="foo.mp4">
    <chunks>
      <file>
        <chunks>
          <file>
          <chunks>
            <file>1</file>
            <file>2</file>
            <file>3</file>
            <file>4</file>
          </chunks>
          </file>
          <file>
          <chunks>
            <file>5</file>
            <file>6</file>
            <file>7</file>
            <file>8</file>
          </chunks>
          </file>
        </chunks>
      </file>
      <file>
        <chunks>
          <file>
          <chunks>
            <file>9</file>
            <file>10</file>
            <file>11</file>
            <file>12</file>
          </chunks>
          </file>
          <file>
          <chunks>
            <file>13</file>
            <file>14</file>
            <file>15</file>
            <file>16</file>
          </chunks>
          </file>
        </chunks>
      </file>
    </chunks>
  </file>
</root>

我只想选择:

<file>1</file>
<file>2</file>
<file>3</file>
<file>4</file>

所以,实际上是这样的:

//[name="foo.mp4"]/chunks/*[1]/chunks/*[1]/*

但是使用一种通用的方法 - 即可以覆盖更深嵌套对象的方法。像这样的:

//[name="foo.mp4"]/(chunks/*[1]/)+/*

(cond)+ 不是 XPath 语法,而是我想要的类似正则表达式的表示。

【问题讨论】:

  • 抱歉,这是一个非常糟糕的需求说明。您实际上是在说“如果输入是 17,那么我希望答案是 23,但我希望这个泛化适用于任何输入”。你需要给我们从输入计算输出的一般规则;我们无法从一个例子中推断出来。

标签: xml xpath recursive-regex


【解决方案1】:

递归意味着自引用,在 XPath 中不能直接使用。忽略中间元素级别的常用方法是通过descendant-or-self 轴 (//),由所需属性锚定。

例如,以下每个 XPath 表达式,

  • 所有值小于 5 的 file 元素:

    //file[number() < 5]
    
  • 前4个叶子file元素:

    //file[not(*)][count(preceding::file[not(*)]) < 4]
    
  • file 叶元素的祖先没有前辈:

    //file[not(*)][not(ancestor::*[preceding::*])]
    

将选择

<file>1</file>
<file>2</file>
<file>3</file>
<file>4</file>

根据要求。

【讨论】:

    【解决方案2】:

    据我所知,没有递归 XPath 这样的东西。因此,您需要将 XPath 与其他一些东西(如 XSLT 或编程语言)结合起来才能进行递归。使用纯 XPath,如果可能,您需要以不同的方式表述需求。

    我不知道这是否适用于您的实际数据,但如果您可以将要求表述为以下内容,例如:

    "在file[@name='foo.mp4'] 内,找到第一个包含叶子 &lt;file&gt;&lt;chunk&gt;&lt;file&gt; 元素,它不包含任何元素,只有文本节点,然后返回叶子 &lt;file&gt;元素"

    那么会有一个可能的纯 XPath 解决方案:

    (//file[@name='foo.mp4']//chunks[not(file/*)])[1]/file
    

    给定有问题的示例 XML,file 1 到 4 的预期输出在测试 here 时由上述 XPath 表达式返回。

    【讨论】:

      猜你喜欢
      • 2016-03-31
      • 2014-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多