如何用XSLT去重:保留重复ID的Active条目及无重复条目
XSLT处理重复Report_Entry条目保留指定状态的解决方案
需求说明
需要用XSLT生成文本文件,处理XML中的重复Report_Entry条目:
- 同一
id存在多个条目时,仅保留status为Active的条目; - 无重复
id时,无论status是Active还是Inactive均保留。
示例XML
<Report_Data> <Report_Entry> <id>1</id> <status>Inactive</status> </Report_Entry> <Report_Entry> <id>1</id> <status>Active</status> </Report_Entry> <Report_Entry> <id>3</id> <status>Active</status> </Report_Entry> <Report_Entry> <id>4</id> <status>Inactive</status> </Report_Entry> </Report_Data>
错误尝试分析
之前的两种写法都存在问题:
group-by="id[../status='Active']":错误地将分组条件限定为包含Active状态的id,导致直接排除了id=4这类唯一的Inactive条目;xsl:for-each-group select="Report_Entry[status='Active']":直接筛选所有Active条目,漏掉了无重复id的Inactive条目。
正确XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 定义分隔符和换行符 --> <xsl:variable name="delimiter" select="'|'"/> <xsl:variable name="newline" select="' '"/> <xsl:template match="Report_Data"> <!-- 输出表头 --> <xsl:text>id|status</xsl:text> <xsl:value-of select="$newline"/> <!-- 按id分组处理每个条目 --> <xsl:for-each-group select="Report_Entry" group-by="id"> <!-- 优先选择组内status为Active的条目 --> <xsl:variable name="active-entry" select="current-group()[status='Active']"/> <!-- 如果存在Active条目则使用它,否则使用组内唯一的条目 --> <xsl:variable name="selected-entry" select="if ($active-entry) then $active-entry else current-group()[1]"/> <!-- 输出条目内容 --> <xsl:value-of select="$selected-entry/id"/> <xsl:value-of select="$delimiter"/> <xsl:value-of select="$selected-entry/status"/> <xsl:value-of select="$newline"/> </xsl:for-each-group> </xsl:template> </xsl:stylesheet>
代码解释
- 分组逻辑:通过
group-by="id"对所有Report_Entry按id分组,确保每个id只被处理一次; - 条目筛选:在每个分组内,先查找是否存在
status='Active'的条目,存在则选中该条目;若不存在,说明该id只有一个条目,直接选中即可; - 文本输出:按指定格式输出选中条目的id和status,确保生成符合要求的文本文件。
预期输出
id|status 1|Active 3|Active 4|Inactive
内容的提问来源于stack exchange,提问作者QnA
相关产品推荐
相关产品推荐

