我可以重构以避免" self ::"和"父母::"?

时间:2016-03-14 15:27:39

标签: xml xpath xpath-1.0

我想提取//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>
  5. (我特别想要<code>foo</code>

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

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

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

    是否有更简洁的表达方式(例如,不需要self::parent::)?

2 个答案:

答案 0 :(得分:3)

尝试消除self::parent::一般来说并不是一个值得称赞的目标。您可能正在搜索这些轴的缩写,希望它们允许缩短的等效表达形式。<​​/ p>

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

/child::a/child:b

可以更简洁地写出

/a/b

self::parent::的并行缩写是什么?

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

但是,在上下文节点或其父节点的名称不重要的情况下,这些更有用 - 在您的情况下不是这样。 (例如,./用于相对路径,而不是/用于绝对路径; ../@attr用于将父元素的attr属性称为与上下文元素的@attr相对。)

因此,简而言之,除了suggested by @JLRishe之外的逻辑简化,您的XPath已经相当简单了。 Axes缩写并没有多大帮助。

答案 1 :(得分:2)

您所拥有的内容似乎是使用self::pre::的理由。如果没有它们,我认为没有更好的方式来表达它。

但是,请注意,您的条件具有的操作数多于其所需的操作数。你可以表达同样的事情:

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