求可实现指定XML输出转换的有效XPath表达式
解决XML节点过滤的XPath方案
看起来你想要保留原XML里的<timestamp>和第二个<record>,移除第一个<record>。你之前尝试的表达式语法有问题,而且没有实现节点过滤的效果,我来帮你梳理正确的方案:
核心需求回顾
输入XML:
<root> <timestamp>2015-12-2</timestamp> <record><e1>123</e1><e2>12366t6</e2></record> <record><e1>123</e1><e2>0000</e2></record> </root>
期望输出:只保留<timestamp>和第二个<record>的<root>结构
正确的XPath方案
1. 支持XPath 2.0+的环境(推荐,可直接生成目标XML)
使用XPath的元素构造语法,直接生成包含所需节点的新<root>:
element root { /root/timestamp, /root/record[position()=2] }
这个表达式会创建一个全新的<root>元素,内部包含原XML的<timestamp>和第二个<record>,完全匹配你想要的输出结果。
2. 仅支持XPath 1.0的环境(需结合节点集操作)
XPath 1.0无法直接构造新节点,但可以先选中需要保留的节点集合:
/root/timestamp | /root/record[2]
这个表达式会返回<timestamp>和第二个<record>的节点集合。如果需要把它们重新包裹在<root>里,通常需要搭配XSLT来完成,比如这样的简单模板:
<xsl:template match="/root"> <root> <xsl:copy-of select="timestamp | record[2]"/> </root> </xsl:template>
你原表达式的问题说明
你尝试的$body/root[/record[2]]存在两个关键问题:
- 内部的
/record[2]是绝对路径,应该改为相对路径record[2],但即使修正为$body/root[record[2]],也只是选择存在第二个record的root节点,不会移除第一个record; - 这个表达式只是选中原有的
<root>节点,不会修改它的子节点内容,所以第一个<record>依然会被保留。
内容的提问来源于stack exchange,提问作者Sourav
相关产品推荐
相关产品推荐

