基于XSLT实现节点计算:收支结余及累计结余XML转换需求
XSLT解决方案:计算年度储蓄与累计储蓄
看起来你需要用XSLT实现年度储蓄(收入-支出)和累计储蓄的计算,同时还要生成指定的注释。我帮你写了一个完整的XSLT解决方案,刚好匹配你的需求,下面是代码和详细解释:
完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 定义键,通过年份快速关联支出节点,避免嵌套循环 --> <xsl:key name="expense-by-year" match="Expense" use="Year"/> <!-- 主模板:匹配输入XML的根节点 --> <xsl:template match="/Input"> <Output> <!-- 生成年度储蓄模块 --> <Savings> <xsl:for-each select="Incomes/Income"> <Saving> <!-- 复制年份节点 --> <xsl:copy-of select="Year"/> <!-- 计算:当年收入 - 当年支出 --> <Amount> <xsl:value-of select="Amount - key('expense-by-year', Year)/Amount"/> </Amount> <!-- 给前两个年份添加注释,最后一个年份跳过 --> <xsl:if test="position() != last()"> <xsl:comment>Income of <xsl:value-of select="Year"/> - Expense of <xsl:value-of select="Year"/></xsl:comment> </xsl:if> </Saving> </xsl:for-each> </Savings> <!-- 生成累计储蓄模块 --> <CumulativeSavings> <!-- 先预计算所有年度的储蓄值,存到变量里方便后续累加 --> <xsl:variable name="all-savings" select="/Input/Incomes/Income/(Amount - key('expense-by-year', Year)/Amount)"/> <xsl:for-each select="Incomes/Income"> <CumulativeSaving> <xsl:copy-of select="Year"/> <!-- 计算从第一年到当前年的储蓄总和 --> <Amount> <xsl:value-of select="sum($all-savings[position() <= current()/position()])"/> </Amount> <!-- 根据年份位置生成对应注释 --> <xsl:comment> <xsl:choose> <xsl:when test="position() = 1"> Income of <xsl:value-of select="Year"/> - Expense of <xsl:value-of select="Year"/> </xsl:when> <xsl:otherwise> Income of <xsl:value-of select="Year"/> - Expense of <xsl:value-of select="Year"/> + Cumulative Saving of <xsl:value-of select="preceding-sibling::Income[1]/Year"/> </xsl:otherwise> </xsl:choose> </xsl:comment> </CumulativeSaving> </xsl:for-each> </CumulativeSavings> </Output> </xsl:template> </xsl:stylesheet>
关键部分解释
用
<xsl:key>优化匹配效率:
定义expense-by-year键后,我们可以直接通过年份快速找到对应的Expense节点,不用嵌套遍历所有支出,让代码更简洁高效。年度储蓄计算:
遍历每个Income节点时,直接用Amount - key('expense-by-year', Year)/Amount得到当年储蓄,同时通过position() != last()判断是否添加注释(和你的输出要求一致,最后一个年份无注释)。累计储蓄计算:
- 先把所有年度的储蓄值存入
all-savings变量; - 遍历每个年份时,用
sum($all-savings[position() <= current()/position()])计算从第一年到当前年的累计总和; - 注释部分通过
<xsl:choose>区分第一个年份和后续年份,生成对应的公式说明。
- 先把所有年度的储蓄值存入
把这个XSLT和你的输入XML一起交给XSLT处理器(比如Saxon、Xalan),就能得到你想要的输出结果啦。
内容的提问来源于stack exchange,提问作者developer
相关产品推荐
相关产品推荐

