2

我想提取//pre//code元素但排除//pre/code. 例如:

<root>
    <pre><code>foo</code></pre>
    <code>bar</code>
    <pre>baz</pre>
    <span>ignore me<code>select me</code></span>
</root>

我想检索四个元素:

  1. <pre><code>foo</code></pre>
  2. <code>bar</code>
  3. <pre>baz</pre>
  4. <code>select me</code>

(而且我特别不想要<code>foo</code>

以下 xpath 似乎可以解决问题:

//*[(self::pre or self::code) and not (self::code and parent::pre)]

我不知道这是否是正确的方法,但它似乎有效。

有没有更简洁的方式来表达这一点(例如,不需要self::and parent::)?

4

2 回答 2

3

试图消除self::parent::通常不是一个值得称赞的目标。您可能正在搜索这些轴的缩写,希望它们允许缩短的等效表达形式。

这是可以理解的,例如,子轴,

/child::a/child:b

可以写得更简洁

/a/b

self::和的平行缩写是parent::什么?

  • self::node()可以缩写.
  • parent::node()可以缩写..

但是,在上下文节点或其父节点的名称无关紧要的情况下,这些更有用 - 在您的情况下并非如此。(例如,./用于相对路径而不是/绝对路径;../@attr用于引用attr父元素的属性而不是@attr上下文元素。)

因此,简而言之,除了@JLRishe 建议的逻辑简化之外,您的 XPath 已经相当简单了。轴缩写不会有太大帮助。

于 2016-03-14T15:45:11.027 回答
2

您在那里拥有的东西似乎是使用self::and的一个很好的理由pre::。我认为没有它们没有更好的方式来表达它。

但是请注意,您的条件的操作数比它需要的多。你可以这样表达同样的事情:

//*[self::pre or (self::code and not(parent::pre))]
于 2016-03-14T16:03:20.933 回答