如何编写XPath获取顶级Case节点的自身文本(排除子节点内容)?
提取XML中顶级节点的起始标签(含属性)
需求
从指定XML文档中提取所有顶级<Case>节点的起始标签(包含全部属性,排除子节点内容),需保留原XML中的换行格式。
源XML文档
<root> <Case When="Initial" Category="Cat One"> <math xmlns="http://www.w3.org/1998/Math/MathML"> <apply> <and/> <ci type="logical" class="Indication">Crit 1</ci> <apply> <or/> <ci type="logical" class="Indication">Crit 2</ci> <ci type="logical" class="Indication">Crit 3</ci> </apply> </apply> </math> <Term Measure="month">6</Term> </Case> <Case When="Initial" Category="Cat Two"> <math xmlns="http://www.w3.org/1998/Math/MathML"> <apply> <and/> <ci type="logical" class="Indication">Crit 1</ci> <apply> <or/> <ci type="logical" class="Indication">Crit 2</ci> <ci type="logical" class="Indication">Crit 3</ci> </apply> </apply> </math> <Term Measure="month">6</Term> </Case> </root>
预期结果
<Case When="Initial" Category="Cat One"> <Case When="Initial" Category="Cat Two">
解决方案
XPath 2.0+ 表达式
若使用支持XPath 2.0及以上版本的处理器(如Saxon),可通过以下表达式构建符合要求的起始标签:
for $case in /root/Case return concat( '<', name($case), string-join( for $attr in $case/@* return concat(' ', name($attr), '="', $attr, '"') ), '>' )
注意:该表达式输出标准化格式的标签,若要完全保留原XML中的换行、缩进,需结合处理器的节点序列化功能配合处理。
原格式保留的补充方案
如果需要严格匹配预期结果的换行和缩进,单纯XPath无法直接保留原XML的空白格式(XPath会忽略节点间的空白文本节点),建议结合XSLT实现:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/root/Case"> <xsl:copy-of select="." copy-namespaces="no"> <xsl:apply-templates mode="strip"/> </xsl:copy-of> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="*" mode="strip"/> </xsl:stylesheet>
该XSLT会复制<Case>节点的起始标签(保留原格式),同时忽略所有子节点,输出完全符合预期的结果。
内容的提问来源于stack exchange,提问作者Anrik
相关产品推荐
相关产品推荐

