如何在 XML 文件中查找不在注释中的特定子字符串?

How to find specific substrings in XML files that aren't inside comments?

在我的 XML 中,我有像 <!--INS--><!--/INS--><!--DEL--><!--/DEL--> 这样的评论;我想在搜索特定子字符串时忽略其中的任何匹配文本。

例如,我的 XML 文件有:

<p>XXXX YYYY ZZZZ 
<!--INS-->,,<!--/INS-->
<!--DEL-->..<!--/DEL-->
AAA BBB CCC DDD..
</p>

我想找到双点元素(p 标签),但需要忽略“INS”和“DEL”标签中的双点。

我试过我的 xpath

//p[contains(.,'..') and descendant::comment()[not(contains(.,'..'))]]

但它不起作用。我如何在 Xpath 代码中执行此操作?

您的“..”和“,”不在 comment() 中,它们在 comment() 之间的文本 () 节点中。 所以如果理解正确你需要这个(错误的假设见编辑):

//p[ends-with(normalize-space(),'..') and not(comment()[contains('INSDEL',.) and following-sibling::node()[1][self::text()[.='..']]])]

这与您的示例不符。

这部分的解释:

following-sibling::node()[1][self::text()

它将 select 直接跟随该评论的文本 ()-节点。

如果你想要只有这个不匹配(两者..)(同样错误的假设见编辑)

<p>XXXX YYYY ZZZZ 
<!--INS-->..<!--/INS-->
<!--DEL-->..<!--/DEL-->
AAA BBB CCC DDD..
</p>

你需要:

    //p[ends-with(normalize-space(),'..') and 
not(comment()[.='INS' and following-sibling::node()[1][self::text()[.='..']]] 
and comment()[.='DEL' and following-sibling::node()[1][self::text()[.='..']]])]

编辑:

以下 XPath:

//p[text()[not(preceding-sibling::node()[1][self::comment()=('INS','DEL') ] ) and contains(.,'..')]]

将匹配此示例:

  <p>Save at least 15% on local breaks, longer trips, or anything in between.. Plan your next getaway for less.
    <!--INS-->Book between Mar.. 15 - 31<!--/INS-->
    <!--DEL-->Stay between May. 15-31<!--/DEL--> Getaway Deals. </p>

因为这两个点在不在注释之间的文本()节点中

但不会匹配

  <p>Save at least 15% on local breaks, longer trips, or anything in between. Plan your next getaway for less.
    <!--INS-->Book between Mar.. 15 - 31<!--/INS-->
    <!--DEL-->Stay between May. 15-31<!--/DEL--> Getaway Deals. </p>

因为唯一的双点在评论之间的文本()节点中

暂时忽略我认为 XPath 表达式的特定注释类型

//p[descendant::text()[contains(., '..')][not(preceding-sibling::node()[1][self::comment()] and following-sibling::node()[1][self::comment()])]]

要仅匹配那些 INSDEL 评论,您可以将其扩展到

//p[descendant::text()[contains(., '..')][not(preceding-sibling::node()[1][self::comment()[. = ('INS', 'DEL')]] and following-sibling::node()[1][self::comment()[. = ('/INS', '/DEL')]])]]

最后,我很想用 XSLT 或 XQuery 预处理输入,将注释“对”之间的点干净地包装到一个容器中,这样 XPath 选择就容易多了。