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

如何用xsl:for-each为每个匹配实例生成按规则命名的独立输出文件?

实现按实例生成独立XML/HTML文件的XSLT方案

需求说明

我有三个文件:1b.xml、2b.xml和try.xsl,想要实现以下目标:

  • 通过xsl:for-each遍历每个<bb>实例,为每个实例生成单独的XML文件(格式如示例)
  • 生成的文件名以<bb>的@date和@num(对应<dd>的@id)命名
  • 利用<bb>的@class值,匹配<gg>和<vv>中对应class值的内容

期望输出格式

<meny>
<mains>
    <meat>chicken</meat>
    <fish>trout</fish>
    <vegetarian>moussaka</vegetarian>
</mains>
<extra>
    <cake>Napoleon cake</cake>
    <drinks>white</drinks>
</extra>
</meny>

现有文件内容

1. try.xsl(当前代码)

<xsl:template match="aa">
  <xsl:variable name="doc2" select="document('2b.xml')"/>
  <body>
    <table>
      <xsl:for-each select="bb">
        <xsl:variable name="bb-num" select="@num"/>
        <xsl:variable name="dd" select="$doc2/cc/dd[@id=$bb-num]"/> 
        <xsl:variable name="bb-class" select="@class"/>
        <xsl:variable name="gg" select="$dd/ff/gg[@class=$bb-class]"/> 
        <xsl:variable name="vv" select="$dd/ff/vv[@class=$bb-class]"/>
         <tr>
           <td><xsl:value-of select="@date"/></td>
           <td><xsl:value-of select="$dd/mm/ee"/></td>
           <td><xsl:value-of select="$gg"/></td>
           <td><xsl:value-of select="$vv"/></td>
         </tr>
       </xsl:for-each>
     </table>        
   </body>
</xsl:template>

2. 1b.xml

<aa>
    <bb date="31.12.2022" num="prs1" class="alt_2"></bb>
    <bb date="07.01.2023" num="prs2" class="alt_1"></bb>
</aa>

3. 2b.xml

<cc>
    <dd id="prs1">
        <mm>
            <ee>steak</ee>
            <nn>salmon</nn>
            <oo>falaffel</oo>
        </mm>
        <ff>
            <gg class="alt_1">carrot cake</gg>
            <gg class="alt_2">chocolate cake</gg>
            <gg class="alt_3">cream cake</gg>
            <vv class="alt_1">red</vv>
            <vv class="alt_2">white</vv>
            <vv class="alt_3">sparkle</vv>  
        </ff>
    </dd>
    <dd id="prs2">
        <mm>
            <ee>chicken</ee>
            <nn>trout</nn>
            <oo>moussaka</oo>
         </mm>        
         <ff>
            <gg class="alt_1">Swiss roll</gg>
            <gg class="alt_2">Napoleon cake</gg>
            <gg class="alt_3">marzipan cake</gg>
            <vv class="alt_1">red</vv>
            <vv class="alt_2">white</vv>
            <vv class="alt_3">sparkle</vv>            
          </ff>
      </dd>    
  </cc>

问题

请问是否可以实现上述需求?


可以实现,以下是修改后的XSLT方案

要生成多个独立文件,需要使用XSLT 2.0及以上版本的<xsl:result-document>元素,它支持动态创建输出文件。以下是适配需求的完整XSLT代码:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:template match="/aa">
        <xsl:variable name="doc2" select="document('2b.xml')"/>
        <!-- 遍历每个bb节点,生成单独文件 -->
        <xsl:for-each select="bb">
            <xsl:variable name="bb-date" select="@date"/>
            <xsl:variable name="bb-num" select="@num"/>
            <!-- 构造文件名:替换日期中的点为下划线,避免系统路径问题 -->
            <xsl:variable name="filename" select="concat(replace($bb-date, '\.', '_'), '_', $bb-num, '.xml')"/>
            
            <xsl:variable name="dd" select="$doc2/cc/dd[@id=$bb-num]"/>
            <xsl:variable name="bb-class" select="@class"/>
            <xsl:variable name="target-gg" select="$dd/ff/gg[@class=$bb-class]"/>
            <xsl:variable name="target-vv" select="$dd/ff/vv[@class=$bb-class]"/>

            <!-- 生成独立输出文件 -->
            <xsl:result-document href="{$filename}">
                <meny>
                    <mains>
                        <meat><xsl:value-of select="$dd/mm/ee"/></meat>
                        <fish><xsl:value-of select="$dd/mm/nn"/></fish>
                        <vegetarian><xsl:value-of select="$dd/mm/oo"/></vegetarian>
                    </mains>
                    <extra>
                        <cake><xsl:value-of select="$target-gg"/></cake>
                        <drinks><xsl:value-of select="$target-vv"/></drinks>
                    </extra>
                </meny>
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

关键说明

  1. 多文件生成:通过<xsl:result-document>指定每个文件的路径和名称,这里用concat和replace处理日期格式,将31.12.2022转为31_12_2022,避免文件名中的点引发系统识别问题。
  2. 数据匹配:保留了原代码中通过@num关联<bb>和<dd>,再通过@class匹配<gg>、<vv>的逻辑,确保数据对应正确。
  3. 输出结构:严格按照给出的期望格式构造<meny>、<mains>、<extra>节点,映射对应的数据字段。

执行要求

需要使用支持XSLT 2.0的处理器(如Saxon 9+、Altova XMLSpy等),XSLT 1.0原生不支持多文件输出,无法实现此需求。


内容的提问来源于stack exchange,提问作者Mats Køber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 07:03:19