如何在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
相关产品推荐
相关产品推荐

