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

使用XSL双for-each将DetailItem值复制到对应行的DetailUnit的AddMe元素

解决方案

这里提供两种实现方式,一种是更高效的键(Key)关联方式,另一种是满足你要求的双for-each遍历方式,可根据实际场景选择。

方式一:使用Key关联(推荐)

通过XSLT的<xsl:key>建立DetailItem的Line值与ID的映射,无需显式嵌套循环,代码简洁高效。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 建立Line值到DetailItem的ID映射 -->
    <xsl:key name="detailItemByLine" match="DetailItem" use="Document/Line"/>
    
    <!-- 身份转换模板:复制所有节点和属性 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 重写AddMe元素的模板,填充对应ID -->
    <xsl:template match="DetailUnit/AddMe">
        <AddMe>
            <!-- 通过当前DetailUnit的LineNumber,查找对应的DetailItem的ID -->
            <xsl:value-of select="key('detailItemByLine', ../DocumentReference/LineNumber)/Document/DocumentID/ID"/>
        </AddMe>
    </xsl:template>
</xsl:stylesheet>

方式二:双for-each遍历实现

如果必须使用两个独立的for-each,可先将DetailItem的Line和ID存储到临时节点集,再遍历DetailUnit匹配赋值:

XSLT 1.0版本(需支持EXSLT扩展)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exslt="http://exslt.org/common"
                extension-element-prefixes="exslt">
    
    <!-- 身份转换模板 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 主模板:先收集DetailItem数据,再处理DetailUnit -->
    <xsl:template match="Element2">
        <xsl:copy>
            <!-- 复制除DetailUnit外的所有子节点 -->
            <xsl:apply-templates select="@*|node()[not(self::DetailUnit)]"/>
            
            <!-- 第一步:遍历DetailItem,存储Line和ID到临时变量 -->
            <xsl:variable name="detailItems">
                <xsl:for-each select="DetailItem">
                    <Item line="{Document/Line}" id="{Document/DocumentID/ID}"/>
                </xsl:for-each>
            </xsl:variable>
            <xsl:variable name="itemNodes" select="exslt:node-set($detailItems)/Item"/>
            
            <!-- 第二步:遍历DetailUnit,匹配对应LineNumber填充AddMe -->
            <xsl:for-each select="DetailUnit">
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()[not(self::AddMe)]"/>
                    <AddMe>
                        <xsl:variable name="currentLine" select="DocumentReference/LineNumber"/>
                        <xsl:value-of select="$itemNodes[@line = $currentLine]/@id"/>
                    </AddMe>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

XSLT 2.0+版本(无需扩展)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <!-- 身份转换模板 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Element2">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[not(self::DetailUnit)]"/>
            
            <!-- 收集DetailItem的Line和ID为序列 -->
            <xsl:variable name="detailItems" as="element(Item)*">
                <xsl:for-each select="DetailItem">
                    <Item line="{Document/Line}" id="{Document/DocumentID/ID}"/>
                </xsl:for-each>
            </xsl:variable>
            
            <!-- 遍历DetailUnit赋值 -->
            <xsl:for-each select="DetailUnit">
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()[not(self::AddMe)]"/>
                    <AddMe>
                        <xsl:value-of select="$detailItems[@line = current()/DocumentReference/LineNumber]/@id"/>
                    </AddMe>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

说明

  • 两种方式均能实现需求:将DetailItem中对应Line的ID值,匹配到DetailUnit中相同LineNumber的AddMe元素内。
  • 方式一的Key关联更高效,适合大数据量场景;方式二严格遵循双for-each遍历逻辑。
  • 转换后的XML会保留原文档结构,仅更新AddMe元素的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 01:10:32