使用XSLT移除文本匹配的Remove_Name节点及对应Keep_Name行
修正XSLT实现XML节点过滤需求
需要处理包含row节点的XML文档,实现以下过滤逻辑:
- 移除所有包含
Remove_Name子节点的row节点 - 移除所有
Keep_Name文本与任一Remove_Name文本匹配的row节点
最终仅保留符合要求的Keep_Name所在row节点。
输入XML
<?xml version="1.0" encoding="UTF-8"?> <root xmlns:map="http://www.w3.org/2005/xpath-functions/map"> <row> <Keep_Name>Africa</Keep_Name> </row> <row> <Keep_Name>USA</Keep_Name> </row> <row> <Keep_Name>Mexico</Keep_Name> </row> <row> <Keep_Name>Canada</Keep_Name> </row> <row> <Keep_Name>Malaysia</Keep_Name> </row> <row> <Remove_Name>Africa</Remove_Name> </row> <row> <Remove_Name>Mexico</Remove_Name> </row> <row> <Remove_Name>Srilanka</Remove_Name> </row> <row> <Keep_Name>Bangladesh</Keep_Name> </row> </root>
期望输出XML
<?xml version="1.0" encoding="UTF-8"?> <root > <row> <Keep_Name>USA</Keep_Name> </row> <row> <Keep_Name>Canada</Keep_Name> </row> <row> <Keep_Name>Malaysia</Keep_Name> </row> <row> <Keep_Name>Bangladesh</Keep_Name> </row> </root>
尝试的未达预期XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="row[.=preceding-sibling::row/.]"/> </xsl:stylesheet>
修正后的XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 收集所有需要移除的名称列表 --> <xsl:variable name="remove-names" select="/root/row/Remove_Name/text()"/> <!-- 身份模板,保留默认节点复制行为 --> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <!-- 匹配需要移除的row节点:包含Remove_Name,或Keep_Name在移除列表中 --> <xsl:template match="row[Remove_Name or Keep_Name/text() = $remove-names]"/> </xsl:stylesheet>
代码说明
- 定义变量
$remove-names,一次性收集所有Remove_Name的文本值,避免重复查询提升效率 - 保留基础身份模板,确保未被标记移除的节点正常复制
- 新增空模板精准匹配两种需移除的
row:- 自身包含
Remove_Name子节点的row Keep_Name文本值存在于$remove-names列表中的row
- 自身包含
内容的提问来源于stack exchange,提问作者Hanu575
相关产品推荐
相关产品推荐

