排除具有额外扭曲的元素之间的节点

时间:2014-05-17 20:56:10

标签: xpath

有一个棘手的XPath问题,我似乎无法得到。让我们说我有以下内容:

<content>
  <body>
      <block id="123">
        <html>
          <p align="left">Some text</p>
        </html>
      </block>
      <block id="abc8383">
        <html>
          <p></p>
        </html>
      </block>
      <block id="456">
        <html>
          <p><span>Some more text</span></p>
         </html>
      </block>
      <block id="789">
        <html>
          <p></p>
        </html>
      </block>  
      <block id="012356">
        <html>
          <p class="finalBlock"><h3>content</h3><span>xyz</span></p>
        </html>
      </block>  
  </body>
</content>

我想在xhtml中使用&#34; finalBlock&#34;选择 标记内的 标记的所有节点。 class,除了没有上下文的那些(节点文本 - 例如块id 789)。但是,此规则应仅适用于再次遇到包含内容的第一个节点 - 之后应包含所有空元素。这意味着上面的输入应该产生以下输出:

<content>
  <body>
      <block id="123">
        <html>
          <p align="left">Some text</p>
        </html>
      </block>
      <block id="abc8383">
        <html>
          <p></p>
        </html>
      </block>
      <block id="456">
        <html>
          <p><span>Some more text</span></p>
         </html>
      </block>  
      <block id="012356">
        <html>
          <p class="finalBlock"><h3>content</h3><span>xyz</span></p>
        </html>
      </block>  
  </body>
</content>

删除了id为789的元素,但保留了所有其他元素。我设法制作了XPath查询,排除了我想要的块元素(空的),但我正在努力实现&#34;之间的#34;规则。任何想法都将不胜感激!

这里的表达式不包括空块元素

//block[html/p]/html/p[normalize-space(.) != '']

1 个答案:

答案 0 :(得分:1)

此表达式选择&{34; p内有html标记的元素,finalBlock类&#34;,<block id="012356">:< / p>

//*[html/p[@class='finalBlock']]

这个节点选择其前面的所有block个节点(&#34;上面的所有节点&#34; - 包含祖先节点):

//*[html/p[@class='finalBlock']]/preceding-sibling::*

您可以添加谓词以将其限制为仅包含非空p后代的谓词:

//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[string()]]

那些具有空p后代的,除了最近的一个:

//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[not(string())]][not(position() = 1)]

如果您执行前两个表达式的 union ,您将获得满足您所述要求的所有block个节点:

//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[string()]] 
| //*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[not(string())]][not(position() = 1)]