You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XSLT中跨层级遍历标签并逐行输出(Apache FOP)

问题描述

作为XSLT新手,我正在用Apache FOP生成AFP文档,现有如下输入XML:

<letter>
 <data>
   <product>
     <a>test</a>
     <b>test1</b>
     <product>
      <charge>
        <one-time-charge>
         <amount>30</amount>
         <info>MNO</info>
        </one-time-charge>
      </charge>
         <product>
          <charge>
           <one-time-charge>
            <amount>10</amount>
            <info>XYZ</info>
           </one-time-charge>
          </charge>
         </product>
         <product>
          <charge>
           <one-time-charge>
            <amount>20</amount>
            <info>ABC</info>
           </one-time-charge>
          </charge>
         </product>
     </product>
    </product>
    </data>
   </letter>

XML中product标签可能有2层或3层,我需要遍历所有层级下的info和amount标签,期望输出如下:

MNO                                       30
XYZ                                       10
ABC                                       20

我尝试用descendant轴写了如下代码:

<xsl:for-each select="data/product/product"> 
 <fo:table-row> 
  <fo:table-cell> 
   <fo:block font-family="Arial" font-size="9pt" font-weight="normal"> 
 <xsl:value-of select="descendant::one-time-charge/info"/> 
 </fo:block> 
 </fo:table-cell> 
<fo:table-cell> 
   <fo:block font-family="Arial" font-size="9pt" font-weight="normal"> 
 <xsl:value-of select="descendant::one-time-charge/amount"/> 
 </fo:block> 
 </fo:table-cell>
 </fo:table-row> 
</xsl:for-each>

但输出结果所有内容都在一行:

MNO XYZ ABC                          301020

请问如何实现逐行输出每个info和对应的amount?

解决方案

问题出在你当前的xsl:for-each选择的是上层product节点,每个这类节点下包含多个one-time-charge,descendant::one-time-charge/info会一次性取出该节点下所有匹配的info值,导致内容堆积在一行。

正确的做法是直接遍历所有one-time-charge节点,不管它处于多少层product下,每个节点对应一行输出:

<xsl:for-each select="descendant::one-time-charge"> 
 <fo:table-row> 
  <fo:table-cell> 
   <fo:block font-family="Arial" font-size="9pt" font-weight="normal"> 
     <xsl:value-of select="info"/> 
   </fo:block> 
  </fo:table-cell> 
  <fo:table-cell> 
   <fo:block font-family="Arial" font-size="9pt" font-weight="normal" text-align="right"> 
     <xsl:value-of select="amount"/> 
   </fo:block> 
  </fo:table-cell>
 </fo:table-row> 
</xsl:for-each>

说明

  • descendant::one-time-charge直接选中所有层级下的one-time-charge节点,每个节点循环一次,自然生成单独一行。
  • 每个one-time-charge节点内部直接选取info和amount,确保两者的对应关系准确。
  • 给amount所在的block添加text-align="right",可以让数值右对齐,更贴近你期望的输出格式。

内容的提问来源于stack exchange,提问作者Pooja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:24:53