如何在XSLT中为非嵌套记录集实现指定嵌套循环匹配逻辑?
实现XSLT中BudgetLine的FundCode映射逻辑
核心思路
遍历每条BudgetLine,先获取其Fund/ID值,再在Funder集合中查找OID与该ID匹配且FFC非空的记录:
- 找到匹配记录:映射该记录的
FFC值 - 未找到或匹配记录的FFC为空:映射原
Fund/ID值
示例输入XML
<Root> <Funders> <Funder> <OID>F001</OID> <FFC>FFC-F001</FFC> </Funder> <Funder> <OID>F002</OID> <FFC></FFC> </Funder> <Funder> <OID>F003</OID> </Funder> </Funders> <BudgetLines> <BudgetLine> <Fund> <ID>F001</ID> </Fund> </BudgetLine> <BudgetLine> <Fund> <ID>F002</ID> </Fund> </BudgetLine> <BudgetLine> <Fund> <ID>F003</ID> </Fund> </BudgetLine> <BudgetLine> <Fund> <ID>F004</ID> </Fund> </BudgetLine> </BudgetLines> </Root>
修改后的XSLT实现
步骤1:定义查找键(优化性能)
先定义一个key,用于快速通过OID定位Funder节点,避免多次全量遍历:
<xsl:key name="funder-by-oid" match="Funder" use="OID" />
步骤2:修改BudgetLine处理模板
替换原有的BudgetLine映射逻辑,加入条件判断:
<xsl:template match="BudgetLine"> <xsl:copy> <!-- 保留原有其他字段的映射逻辑 --> <FundCode> <!-- 获取当前BudgetLine的Fund/ID --> <xsl:variable name="current-fund-id" select="Fund/ID" /> <!-- 查找符合条件的Funder:OID匹配 + FFC非空 --> <xsl:variable name="matched-funder" select="key('funder-by-oid', $current-fund-id)[normalize-space(FFC) != '']" /> <!-- 分支处理映射值 --> <xsl:choose> <xsl:when test="$matched-funder"> <xsl:value-of select="$matched-funder/FFC" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$current-fund-id" /> </xsl:otherwise> </xsl:choose> </FundCode> <!-- 保留原有其他节点的处理 --> </xsl:copy> </xsl:template>
XSLT 3.0简化写法
如果使用XSLT 3.0,可以用更简洁的表达式替代xsl:choose:
<FundCode> <xsl:value-of select="let $fund-id := Fund/ID, $valid-funder := key('funder-by-oid', $fund-id)[normalize-space(FFC)] return if ($valid-funder) then $valid-funder/FFC else $fund-id" /> </FundCode>
预期输出XML
<Root> <Funders> <Funder> <OID>F001</OID> <FFC>FFC-F001</FFC> </Funder> <Funder> <OID>F002</OID> <FFC></FFC> </Funder> <Funder> <OID>F003</OID> </Funder> </Funders> <BudgetLines> <BudgetLine> <FundCode>FFC-F001</FundCode> </BudgetLine> <BudgetLine> <FundCode>F002</FundCode> </BudgetLine> <BudgetLine> <FundCode>F003</FundCode> </BudgetLine> <BudgetLine> <FundCode>F004</FundCode> </BudgetLine> </BudgetLines> </Root>
内容的提问来源于stack exchange,提问作者manibest
相关产品推荐
相关产品推荐

