如何在 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()])]]
要仅匹配那些 INS
和 DEL
评论,您可以将其扩展到
//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 选择就容易多了。
在我的 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()])]]
要仅匹配那些 INS
和 DEL
评论,您可以将其扩展到
//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 选择就容易多了。