使用XSLT 1.0移除重复状态码并生成单状态transport节点
XSLT 1.0 实现去重并拆分transport节点
输入示例XML
<root> <transport> <complex_structure_nested_1> <some_data>foo</some_data> <nested>bar</nested> </complex_structure_nested_1> <statuses last_status_code="ACTIVE"> <status code="ACTIVE"/> <status code="INACTIVE"/> <status code="ACTIVE"/> <status code="PENDING"/> </statuses> </transport> <transport> <complex_structure_nested_2> <another_data>baz</another_data> </complex_structure_nested_2> <statuses last_status_code="INACTIVE"> <status code="INACTIVE"/> <status code="INACTIVE"/> </statuses> </transport> </root>
目标输出XML
<root> <transport> <complex_structure_nested_1> <some_data>foo</some_data> <nested>bar</nested> </complex_structure_nested_1> <statuses last_status_code="ACTIVE"> <status code="ACTIVE"/> </statuses> </transport> <transport> <complex_structure_nested_1> <some_data>foo</some_data> <nested>bar</nested> </complex_structure_nested_1> <statuses last_status_code="ACTIVE"> <status code="INACTIVE"/> </statuses> </transport> <transport> <complex_structure_nested_1> <some_data>foo</some_data> <nested>bar</nested> </complex_structure_nested_1> <statuses last_status_code="ACTIVE"> <status code="PENDING"/> </statuses> </transport> <transport> <complex_structure_nested_2> <another_data>baz</another_data> </complex_structure_nested_2> <statuses last_status_code="INACTIVE"> <status code="INACTIVE"/> </statuses> </transport> </root>
XSLT 1.0 转换代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 复制所有节点和属性的基础模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理transport节点:为每个唯一status生成新的transport --> <xsl:template match="transport"> <!-- 使用Muenchian方法分组去重status的code值 --> <xsl:key name="unique-status" match="status" use="@code"/> <!-- 遍历当前transport下的所有唯一status --> <xsl:for-each select="statuses/status[generate-id() = generate-id(key('unique-status', @code)[1])]"> <!-- 复制原transport节点除statuses外的所有内容 --> <xsl:copy-of select="ancestor::transport/*[not(self::statuses)]"/> <!-- 生成新的statuses节点,保留原last_status_code属性 --> <statuses> <xsl:copy-of select="ancestor::transport/statuses/@last_status_code"/> <!-- 复制当前唯一的status节点 --> <xsl:copy-of select="."/> </statuses> </xsl:for-each> </xsl:template> </xsl:stylesheet>
代码说明
- 基础复制模板:原样复制所有未被特殊模板匹配的节点和属性,确保原复杂嵌套结构完整保留。
- Muenchian分组去重:通过
<xsl:key>定义分组键,以status的code属性为依据,筛选出每个code对应的第一个节点,实现重复code的去重。 - 拆分transport节点:对每个transport下的唯一status,先复制原transport中除statuses外的所有内容,再生成保留原
last_status_code属性的新statuses节点,里面只包含当前唯一的status。
内容的提问来源于stack exchange,提问作者Enrico Barsali
相关产品推荐
相关产品推荐

