如何用XSLT筛选前置为<pc>节点的<phr function="adversative">节点
解决XSLT匹配紧邻前一个节点为的节点问题
嘿,我明白你的问题了——你想抓取那些function="adversative"的<phr>节点,但只有当它们**紧挨着前面的节点是<pc>(句号)**的时候才匹配对吧?之前用preceding-sibling轴没得到结果,大概率是因为没限定「紧邻」这个条件,我来给你捋清楚怎么写:
核心匹配逻辑
preceding-sibling轴默认会选中当前节点之前的所有兄弟节点,而你需要的是紧邻的前一个节点。所以必须用位置谓词[1]来锁定离当前节点最近的那个兄弟,再判断它是不是<pc>节点。
正确的匹配表达式有两种写法,效果一致:
- 先锁定紧邻前一个节点,再判断类型:
phr[@function='adversative'][preceding-sibling::*[1][self::pc]] - 直接筛选紧邻的前一个
<pc>节点(因为preceding-sibling::pc[1]会选中离当前节点最近的<pc>兄弟,也就是紧邻的那个):phr[@function='adversative'][preceding-sibling::pc[1]]
完整XSLT示例
下面是一个可直接使用的样式表,会输出所有符合条件的<phr>节点内容:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配符合条件的phr节点,自定义输出格式 --> <xsl:template match="phr[@function='adversative'][preceding-sibling::*[1][self::pc]]"> <matched-adversative-phrase> <xsl:value-of select="."/> </matched-adversative-phrase> </xsl:template> <!-- 忽略其他节点,避免输出原XML的冗余内容 --> <xsl:template match="text()|@*"/> </xsl:stylesheet>
测试XML示例
用下面的XML测试,看看效果:
<text-content> <!-- 符合条件:phr紧邻pc之后 --> <pc>.</pc> <phr function="adversative">但是</phr> <!-- 不符合条件:phr前面是word节点 --> <word>测试文本</word> <phr function="adversative">然而</phr> <!-- 符合条件:中间无其他节点 --> <pc>.</pc> <phr function="adversative">不过</phr> <!-- 不符合条件:pc和phr之间有其他节点 --> <pc>.</pc> <note>注释内容</note> <phr function="adversative">却</phr> </text-content>
转换结果
运行样式表后,只会输出符合条件的两个节点:
<matched-adversative-phrase>但是</matched-adversative-phrase> <matched-adversative-phrase>不过</matched-adversative-phrase>
这样就精准匹配到了你需要的节点啦!
内容的提问来源于stack exchange,提问作者Miguel Las Heras
相关产品推荐
相关产品推荐

