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

XML-FO转换中基于KeyName的XPath for-each去重循环需求

实现XML中唯一KeyName节点的单次XSL-FO转换

嘿,这个需求用XSLT的分组特性就能完美解决!我们可以先把重复的KeyName按文本值分组,然后只对每个分组里的第一个节点执行FO转换逻辑,这样就能保证每个唯一的KeyName只被处理一次。下面是完整的代码和说明:

第一步:定义分组键与基础FO结构

首先我们需要在XSLT里定义一个分组键,用来把相同KeyName的Row节点归为一组,同时搭建FO文档的基础框架:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <!-- 定义分组规则:按KeyName的文本值对Row节点分组 -->
    <xsl:key name="uniqueKeyGroups" match="Row" use="KeyName"/>

    <!-- 匹配根节点,生成FO文档的核心结构 -->
    <xsl:template match="/root">
        <fo:root>
            <!-- 定义页面模板 -->
            <fo:layout-master-set>
                <fo:simple-page-master master-name="default-page" page-width="210mm" page-height="297mm">
                    <fo:region-body margin="20mm"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            
            <fo:page-sequence master-reference="default-page">
                <fo:flow flow-name="xsl-region-body">
                    <!-- 只选择每个分组里的第一个Row节点,实现去重 -->
                    <xsl:apply-templates select="Row[generate-id() = generate-id(key('uniqueKeyGroups', KeyName)[1])]"/>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>

第二步:编写唯一KeyName的FO处理逻辑

接下来,我们为每个唯一的KeyName编写具体的FO转换模板,这里以生成标题和示例内容为例,你可以根据自己的需求替换成对应的格式:

<!-- 处理每个唯一的KeyName分组 -->
    <xsl:template match="Row">
        <!-- 输出KeyName作为加粗标题 -->
        <fo:block font-size="16pt" font-weight="bold" margin-bottom="8mm">
            唯一标识:<xsl:value-of select="KeyName"/>
        </fo:block>

        <!-- 这里添加你需要的自定义处理逻辑 -->
        <fo:block font-size="12pt" line-height="1.5" margin-bottom="12mm">
            针对<xsl:value-of select="KeyName"/>的专属FO内容,比如表格、段落、图片等都可以在这里定义。
        </fo:block>
    </xsl:template>
</xsl:stylesheet>

核心逻辑解释

  • <xsl:key>:这个标签定义了分组规则,把所有Row节点按照KeyName的文本值分成不同的组,相同KeyName的节点会被分到同一组。
  • Row[generate-id() = generate-id(key('uniqueKeyGroups', KeyName)[1])]:这个选择器是关键!它会筛选出每个分组中的第一个Row节点,因为同一组内的所有节点调用generate-id(key('uniqueKeyGroups', KeyName)[1])都会得到同一个ID,只有组内第一个节点的generate-id()会和它相等,这样就实现了自动去重。
  • 你可以完全自定义Row模板里的FO内容,比如生成报表表格、插入图片、设置复杂样式等,只要是该KeyName需要的处理逻辑都放在这里就行。

用这个XSLT处理你的XML后,重复的A和B都会只被处理一次,C也会正常输出,最终生成的FO文档里每个唯一KeyName对应一份处理结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:54:41