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

如何用XSLT 1.0匹配元素属性值并求和生成新属性

XSLT新手求助:匹配属性并计算生成新属性

需求

匹配每个SOURCE元素的name属性与BLOCK元素的name属性,匹配成功后,将对应BLOCK的X属性值与SOURCE的id属性值求和,生成新的pointX属性。

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<puzzle>    
    <BLOCKS>
        <BLOCK X="12" name="BL_01"></BLOCK>
        <BLOCK X="12" name="BL_02"></BLOCK>
        <BLOCK X="12" name="BL_03"></BLOCK>
    </BLOCKS>
    <CONNEXIONS>
        <CONNEXION>
            <SOURCE name="BL_01" id="4"></SOURCE>
        </CONNEXION>
        <CONNEXION>
            <SOURCE name="BL_03" id="1"></SOURCE>
        </CONNEXION>
        <CONNEXION>
            <SOURCE name="BL_02" id="8"> </SOURCE>
        </CONNEXION>
    </CONNEXIONS>
</puzzle>

期望输出XML

<program>
        <lSource>
            <space pointX="16" ></space>
        </lSource>
        <lSource>
            <space pointX="13" ></space>
        </lSource>
        <lSource>
            <space pointX="20" ></space>
        </lSource>
</program>

尝试的XSLT代码(无法正常运行)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ex="http://exslt.org/dates-and-times" exclude-result-prefixes="ex">
    <xsl:output version="1.0" encoding="UTF-8" standalone="yes" indent="yes" method="html"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <program>
        <xsl:for-each select="puzzle/CONNEXIONS/CONNEXION">
                <lSource>
                    <space>
                    <xsl:for-each select="puzzle/CONNEXIONS/CONNEXION/SOURCE">
                    <xsl:if test="CONNEXION/SOURCE/@name] != BLOCK/@name]">
                    <xsl:attribute name="PointX">
                    <xsl:value-of select="puzzle/BLOCKS/BLOCK/@X+puzzle/CONNEXIONS/CONNEXION/SOURCE/@id"/>
                    </xsl:attribute>                      
                    </xsl:for-each>
                    </space>
                </lSource>
        </program>
    </xsl:template>
 </xsl:stylesheet>

问题分析与修正代码

原代码问题点

  • 路径错误:遍历CONNEXION时,内部重复全量遍历所有SOURCE,未使用相对路径定位当前节点下的SOURCE
  • 匹配逻辑错误:xsl:if条件写反,且存在语法错误(多余]符号)
  • 求和路径错误:直接选取所有BLOCK的X值,未根据SOURCE的name匹配对应BLOCK
  • 输出方法错误:使用method="html",但需要生成XML格式内容

修正后的XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output version="1.0" encoding="UTF-8" standalone="yes" indent="yes" method="xml"/>
    <xsl:strip-space elements="*"/>
    
    <!-- 定义键,通过name属性快速定位BLOCK元素 -->
    <xsl:key name="block-by-name" match="BLOCK" use="@name"/>

    <xsl:template match="/">
        <program>
            <!-- 遍历每个CONNEXION节点 -->
            <xsl:for-each select="puzzle/CONNEXIONS/CONNEXION">
                <lSource>
                    <space>
                        <!-- 获取当前CONNEXION下的SOURCE -->
                        <xsl:variable name="current-source" select="SOURCE"/>
                        <!-- 通过键匹配对应name的BLOCK -->
                        <xsl:variable name="matched-block" select="key('block-by-name', $current-source/@name)"/>
                        <!-- 计算求和值并生成pointX属性 -->
                        <xsl:attribute name="pointX">
                            <xsl:value-of select="$matched-block/@X + $current-source/@id"/>
                        </xsl:attribute>
                    </space>
                </lSource>
            </xsl:for-each>
        </program>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. 用<xsl:key>建立BLOCK的name属性索引,提升匹配效率
  2. 遍历CONNEXION时,通过相对路径获取当前节点下的SOURCE
  3. 利用索引匹配对应name的BLOCK,将两者属性值转为数值求和
  4. 输出方法改为xml,确保生成标准XML格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:45:28