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

Xpath 排除具有额外扭曲的图元之间的节点,xpath,Xpath,有一个棘手的XPath问题,我似乎不太明白。假设我有以下几点: <content> <body> <block id="123"> <html> <p align="left">Some text</p> </html> </block> <block id="abc8383"> &

有一个棘手的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>
此表达式选择“在
html
中具有
p
标记且带有
finalBlock
类的元素”,即

这一个选择它前面的所有
节点(“上面的所有节点”-不包括祖先节点):

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

//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[string()]]
以及具有空
p
子代的子代,但最近的子代除外:

//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[not(string())]][not(position() = 1)]
如果执行前两个表达式的并集,则将获得满足所述要求的所有
节点:

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

你能展示一下你在最后一段提到的XPath表达式吗?当然-它是://block[html/p]/html/p[normalize space(.)!=''你的XPath选择了
p
。要选择
p
?所需输出甚至具有
内容
节点。XPath只允许您选择文档的某些部分,而不允许像这样进行转换。要执行这样的转换,需要XSLT。顺便说一句,这里有一个表达式,用于选择满足条件的块
//block[html/p[normalize space(.)!='''或以下同级::block/html/p[not(@class='finalBlock')和normalize space(.)!=']
,至少对于您显示的输入和输出是这样。我假设只有一个
finalBlock
,并且
finalBlock
不算是第一个再次遇到内容的
节点
,谢谢Tom-您提供的内容似乎与广告中的一样有效。我确实使用XSLT,但它很大,而且还做了很多其他事情,所以我想在XPath的上下文中提出这个问题,我将很快插入XSLT中。:)谢谢-这非常有效,但有一个小例外。。。我还需要它返回带有“finalBlock”类的block元素-为此需要对上面的内容进行哪些修改?您可以将其添加到结果节点集(它在上面的第一个表达式中被选中:
/*[html/p[@class='finalBlock']]
//block[html/p[@class='finalBlock']]
。只需附加
|//块[html/p[@class='finalBlock']]
//*[html/p[@class='finalBlock']]/preceding-sibling::*
//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[string()]]
//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[not(string())]][not(position() = 1)]
//*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[string()]] 
| //*[html/p[@class='finalBlock']]/preceding-sibling::*[descendant::p[not(string())]][not(position() = 1)]