如何修改XSLT实现XML转CSV时Details子节点单独换行
解决XML转CSV时子节点单独成行的问题
以下是针对需求修改后的XSLT代码,实现每个Details节点内容单独占一行的带引号CSV输出,同时兼容字段中含双引号的转义处理:
输入XML示例
<Root> <TrRecords> <TrID>TR001</TrID> <TrDate>2024-05-20</TrDate> <Details> <ItemID>ITEM001</ItemID> <Qty>5</Qty> <Price>10.99</Price> </Details> <Details> <ItemID>ITEM002</ItemID> <Qty>2</Qty> <Price>15.50</Price> </Details> </TrRecords> <TrRecords> <TrID>TR002</TrID> <TrDate>2024-05-21</TrDate> <Details> <ItemID>ITEM003</ItemID> <Qty>1</Qty> <Price>29.99</Price> </Details> </TrRecords> </Root>
修改后的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 转义CSV中的双引号:将单个"替换为"" --> <xsl:template name="escape-quotes"> <xsl:param name="text"/> <xsl:choose> <xsl:when test="contains($text, '"')"> <xsl:value-of select="substring-before($text, '"')"/> <xsl:text>""</xsl:text> <xsl:call-template name="escape-quotes"> <xsl:with-param name="text" select="substring-after($text, '"')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="/"> <!-- 输出CSV表头 --> <xsl:text>"TrID","TrDate","ItemID","Qty","Price" </xsl:text> <!-- 遍历每个父交易记录节点 --> <xsl:for-each select="Root/TrRecords"> <!-- 缓存父节点固定字段,避免重复查询 --> <xsl:variable name="tr-id"> <xsl:call-template name="escape-quotes"> <xsl:with-param name="text" select="TrID"/> </xsl:call-template> </xsl:variable> <xsl:variable name="tr-date"> <xsl:call-template name="escape-quotes"> <xsl:with-param name="text" select="TrDate"/> </xsl:call-template> </xsl:variable> <!-- 为每个Details节点单独输出一行 --> <xsl:for-each select="Details"> <xsl:text>"</xsl:text><xsl:value-of select="$tr-id"/><xsl:text>","</xsl:text> <xsl:value-of select="$tr-date"/><xsl:text>","</xsl:text> <xsl:text>"</xsl:text> <xsl:call-template name="escape-quotes"> <xsl:with-param name="text" select="ItemID"/> </xsl:call-template> <xsl:text>","</xsl:text> <xsl:text>"</xsl:text> <xsl:call-template name="escape-quotes"> <xsl:with-param name="text" select="Qty"/> </xsl:call-template> <xsl:text>","</xsl:text> <xsl:text>"</xsl:text> <xsl:call-template name="escape-quotes"> <xsl:with-param name="text" select="Price"/> </xsl:call-template> <xsl:text>" </xsl:text> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 换行控制:通过
输出换行符,确保每个Details节点对应单独一行 - 字段转义:新增
escape-quotes模板,严格遵循CSV规范处理含双引号的字段 - 性能优化:缓存父节点的
TrID和TrDate字段,避免在遍历Details时重复查询
预期CSV输出
"TrID","TrDate","ItemID","Qty","Price" "TR001","2024-05-20","ITEM001","5","10.99" "TR001","2024-05-20","ITEM002","2","15.50" "TR002","2024-05-21","ITEM003","1","29.99"
内容的提问来源于stack exchange,提问作者janardhan d
相关产品推荐
相关产品推荐

