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

如何在XSLT中通过ID引用获取并显示对应Item的名称

解决XSLT显示item名称而非ID的问题

问题背景

现有XML文档包含item节点(含id属性与NAME子节点)与owner节点,每个owner可通过property节点引用多个item。当前XSLT导出Max的所有item时,仅显示item的引用ID(如a01),需改为显示对应的NAME内容(如name of item a1)。

原XML代码

<?xml version="1.0" encoding="UTF-8"?>
<MYDATA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <item id="a01">
        <NAME>name of item a1</NAME>
    </item>
    <item id="a02">
        <NAME>name of item a2</NAME>
    </item>
    <item id="a03">
        <NAME>name of item a3</NAME>
    </item>
    <owner>
        <name>Max</name>
        <owns>
            <property prop_id="a01">
                <DATE_BOUGHT>1</DATE_BOUGHT>
            </property>
            <property prop_id="a02">
                <DATE_BOUGHT>2</DATE_BOUGHT>
            </property>
        </owns>
    </owner>
    <owner>
        <name>Anna</name>
        <owns>
            <property prop_id="a01">
                <DATE_BOUGHT>3</DATE_BOUGHT>
            </property>
            <property prop_id="a03">
                <DATE_BOUGHT>2</DATE_BOUGHT>
            </property>
        </owns>
    </owner>
</MYDATA>

原XSLT代码(存在问题)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <head>
                <title>Max's items</title>
            </head>
            <body>
                <h1>Max's items</h1>
                <h2>List of all items owned by Max </h2>
                <table border="1">
                    <tr bgcolor="#9acd32">
                        <th align="left">Title</th>
                        <th align="left">borrowed since</th>
                    </tr>
                    <xsl:for-each select="MYDATA/owner[name = 'Max']/owns/property">
                        <xsl:sort select="DATE_BOUGHT"/>
                        <xsl:key name="item-by-id" match="item" use="@id"/>
                        <tr>
                            <td>
                                <xsl:value-of select="key('item-by-id', @prop_id)/NAME"/>
                            </td>
                            <td>
                                <xsl:value-of select="DATE_BOUGHT"/>
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

当前错误输出

<html>
    <head>
        <META http-equiv="Content-Type" content="text/html">
            <title>Max's items</title>
        </head>
        <body>
            <h1>Max's items</h1>
            <h2>List of all items owned by Max </h2>
            <table border="1">
                <tr bgcolor="#9acd32">
                    <th align="left">Name</th>
                    <th align="left">DATE_BOUGHT</th>
                </tr>
                <tr>
                    <td>a01</td>
                    <td>1</td>
                </tr>
                <tr>
                    <td>a02</td>
                    <td>2</td>
                </tr>
            </table>
        </body>
    </html>

问题原因

原XSLT中<xsl:key>定义在<xsl:for-each>内部,违反了XSLT 1.0的规则:key必须定义在stylesheet的顶层(直接作为<xsl:stylesheet>的子节点),导致key未生效,无法通过prop_id找到对应的item节点,最终 fallback 显示了property的prop_id属性值。

修改后的XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 将key移到顶层,全局生效 -->
    <xsl:key name="item-by-id" match="item" use="@id"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>Max's items</title>
            </head>
            <body>
                <h1>Max's items</h1>
                <h2>List of all items owned by Max </h2>
                <table border="1">
                    <tr bgcolor="#9acd32">
                        <!-- 修正表头文字,匹配期望输出 -->
                        <th align="left">Name</th>
                        <th align="left">DATE_BOUGHT</th>
                    </tr>
                    <xsl:for-each select="MYDATA/owner[name = 'Max']/owns/property">
                        <xsl:sort select="DATE_BOUGHT"/>
                        <tr>
                            <td>
                                <!-- 通过key匹配item,取出NAME值 -->
                                <xsl:value-of select="key('item-by-id', @prop_id)/NAME"/>
                            </td>
                            <td>
                                <xsl:value-of select="DATE_BOUGHT"/>
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

修改说明

  1. 移动key位置:将<xsl:key>从for-each内部移到stylesheet顶层,确保全局可访问,正确建立item的id索引。
  2. 修正表头文字:将Title改为Name,borrowed since改为DATE_BOUGHT,与期望输出一致。
  3. 保留原有逻辑:保留按DATE_BOUGHT排序、筛选Max的item等逻辑,确保功能不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:20:35