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

含交叉引用的XML转换:XSL中如何实现Material属性赋值?

处理XML交叉引用的XSLT解决方案

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<Project>
    <RessourcePool>
        <Stock Ref="Ref_1" Name="135gl" Weight="135" WeightUnit="gsm"/>
        <Stock Ref="Ref_2" Name="300ma" Weight="300" WeightUnit="gsm"/>
    </RessourcePool>
    <Product Type="Bound">
        <StockRef rRef="Ref_1"/>
    </Product>
    <Product Type="Unbound">
        <StockRef rRef="Ref_2"/>
    </Product>
</Project>

初始XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <xsl:for-each select="//Product">
                <xsl:variable name="elem-name">
                    <xsl:choose>
                        <xsl:when test='@Type="Bound"'>BoundComponent</xsl:when>
                        <xsl:otherwise>UnboundComponent</xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:element name="{$elem-name}">
                <!-- 需要添加Material属性:匹配Product的StockRef与RessourcePool中的Stock,将Stock的@Name、@Weight和@WeightUnit按格式"135gl, 135gsm"赋值 -->
                </xsl:element>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

修改后的XSLT代码

使用<xsl:key>创建索引高效处理交叉引用,替代低效的循环判断:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    
    <!-- 定义索引键:以Stock的Ref属性为键,快速定位对应的Stock元素 -->
    <xsl:key name="stock-by-ref" match="Stock" use="@Ref"/>

    <xsl:template match="/">
        <xsl:for-each select="//Product">
            <xsl:variable name="elem-name">
                <xsl:choose>
                    <xsl:when test='@Type="Bound"'>BoundComponent</xsl:when>
                    <xsl:otherwise>UnboundComponent</xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <!-- 获取当前Product对应的Stock引用ID -->
            <xsl:variable name="stock-ref" select="StockRef/@rRef"/>
            <!-- 通过索引键查找匹配的Stock元素 -->
            <xsl:variable name="matched-stock" select="key('stock-by-ref', $stock-ref)"/>
            
            <xsl:element name="{$elem-name}">
                <!-- 找到匹配Stock时生成Material属性 -->
                <xsl:if test="$matched-stock">
                    <xsl:attribute name="Material">
                        <xsl:value-of select="concat($matched-stock/@Name, ', ', $matched-stock/@Weight, $matched-stock/@WeightUnit)"/>
                    </xsl:attribute>
                </xsl:if>
            </xsl:element>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

关键说明

  • 索引优化:<xsl:key>为所有<Stock>元素建立基于Ref属性的索引,后续通过key()函数可直接定位匹配元素,比循环遍历<RessourcePool/Stock>效率更高,数据量越大优势越明显。
  • 属性拼接:用concat()函数将Name、Weight、WeightUnit按要求格式组合,生成Material属性值。
  • 空值防护:通过<xsl:if test="$matched-stock">确保仅在找到有效匹配时才生成Material属性,避免空属性出现。

转换结果

执行上述XSLT后,输出XML如下:

<?xml version="1.0" encoding="UTF-8"?>
<BoundComponent Material="135gl, 135gsm"/>
<UnboundComponent Material="300ma, 300gsm"/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:57:06