如何用XSLT将含peci:priorValue属性的XML转为多行CSV?
解决XSLT转换XML到CSV时的行合并问题
核心思路
针对每个带有peci:priorValue属性的元素,分别生成两行CSV记录:一行对应旧值(priorValue属性内容),一行对应当前值(元素文本内容)。关键是为每个符合条件的元素触发两次输出,而非合并成单行。
示例XML(基于常见场景假设)
<root xmlns:peci="http://example.com/peci"> <field id="username" peci:priorValue="old_jack">new_jack</field> <field id="email" peci:priorValue="jack@old.com">jack@new.com</field> </root>
期望CSV输出
username,old_jack username,new_jack email,jack@old.com email,jack@new.com
正确的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:peci="http://example.com/peci"> <xsl:output method="text" encoding="UTF-8"/> <!-- 处理根节点,触发目标元素的模板匹配 --> <xsl:template match="/"> <!-- 可选:如需表头,取消下方注释 <xsl:text>FieldID,Value </xsl:text> --> <xsl:apply-templates select="//*[@peci:priorValue]"/> </xsl:template> <!-- 匹配所有带peci:priorValue属性的元素 --> <xsl:template match="*[@peci:priorValue]"> <!-- 输出旧值行 --> <xsl:value-of select="@id"/> <xsl:text>,</xsl:text> <xsl:value-of select="@peci:priorValue"/> <xsl:text> </xsl:text> <!-- 输出当前值行 --> <xsl:value-of select="@id"/> <xsl:text>,</xsl:text> <xsl:value-of select="text()"/> <xsl:text> </xsl:text> </xsl:template> <!-- 忽略无关节点,避免冗余输出 --> <xsl:template match="text()|@*"/> </xsl:stylesheet>
关键说明
- 用
//*[@peci:priorValue]全局匹配所有带目标属性的元素,确保不遗漏需要处理的字段。 - 对每个匹配元素,先后输出旧值行和当前值行,用
添加换行符实现CSV的行分隔。 - 最后一个模板用于过滤XML中不需要处理的文本和属性,避免输出无效内容。
如果你的XML结构和示例不同(比如元素名不是field、标识属性不是id),只需调整模板中对应的属性或元素匹配规则即可。
内容的提问来源于stack exchange,提问作者Viji Niranjan
相关产品推荐
相关产品推荐

