如何用XSLT将XML支付列转为单独行(支持动态列)
解决方案:动态拆分XML支付列为单独行
可行性说明
完全可行,XSLT支持动态匹配XML元素,不需要硬编码所有支付列名称,新增支付列后无需修改XSLT即可自动处理。
问题分析
你之前的代码存在两个核心问题:
- 原XML中不存在
Item元素,你匹配了错误的节点; - 逻辑未实现将每个支付列拆分为单独行的需求,仅尝试转换列结构。
完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- 存储表头行的所有列名 --> <xsl:variable name="headers" select="/Report/Row[1]/*"/> <xsl:template match="/"> <Report> <!-- 遍历所有数据行(跳过第一行表头) --> <xsl:for-each select="/Report/Row[position() > 1]"> <!-- 存储当前员工的ID和NAME --> <xsl:variable name="empId" select="*[1]"/> <xsl:variable name="empName" select="*[2]"/> <!-- 遍历当前行的所有支付列(从第3列开始) --> <xsl:for-each select="*[position() >= 3]"> <Row> <ID><xsl:value-of select="$empId"/></ID> <NAME><xsl:value-of select="$empName"/></NAME> <!-- 获取对应表头的支付类型,去掉空格 --> <PAYTYPE> <xsl:value-of select="translate($headers[position()], ' ', '')"/> </PAYTYPE> <!-- 处理金额:0.00转为0,其他保留原内容 --> <AMOUNT> <xsl:choose> <xsl:when test=". = '0.00'">0</xsl:when> <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise> </xsl:choose> </AMOUNT> </Row> </xsl:for-each> </xsl:for-each> </Report> </xsl:template> </xsl:stylesheet>
代码关键说明
- 动态获取表头:通过
$headers变量存储第一行的所有列元素,后续通过位置对应获取支付类型名称; - 遍历支付列:对每个数据行,只处理从第3个元素开始的列(即所有支付列),每个列生成一个新的
<Row>; - 支付类型格式化:用
translate函数去掉表头名称中的空格,比如将SICK PAY转为SICKPAY; - 金额处理:通过
xsl:choose判断金额是否为0.00,如果是则输出0,否则保留原数值; - 扩展性:新增支付列(比如
<col7>OVERTIME PAY</col7>)后,XSLT会自动识别并生成对应的行,无需修改代码。
转换效果
该代码会将你提供的输入XML转换为你期望的输出格式,且支持任意新增的支付列。
内容的提问来源于stack exchange,提问作者AJW
相关产品推荐
相关产品推荐

