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

如何修正XSLT代码以输出符合预期的每周菜单结果

问题根因

你的代码无法输出菜品,核心是3个XSLT 1.0的基础语法问题:

  1. 结果树片段(RTF)无法直接查询:XSLT 1.0中,用<xsl:variable>包裹模板输出生成的是结果树片段,标准语法不支持直接用XPath选取RTF内的节点,所以你写的$menu/dish匹配不到任何菜品,循环不会执行。
  2. 缺少换行控制符:XSLT输出文本时,标签之间的空白默认会被压缩忽略,你没有手动加换行符(&#xA;),就算能输出菜品也会全部挤在同一行。
  3. 周数参数与预期不匹配:你给出的预期输出对应week参数值为4,不是代码里写的2,原位置公式是标准的循环选菜逻辑(到分类最后一个菜品后回到第一个循环),如果需要停在最后一个不循环可以自行调整判断逻辑。
最简单的修改方案(适合初学者)

完全放弃用变量存储中间菜单的写法,直接在根模板里计算每个分类要选的菜品、输出内容,彻底避开RTF限制,逻辑更直观:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>

<!-- 预期输出对应week值为4,可自行修改 -->
<xsl:param name="week" select="4"/>

<!-- 封装计算菜品位置的逻辑,标准循环规则:到最后一个后回到第一个 -->
<xsl:template name="get-position">
    <xsl:param name="total"/>
    <xsl:variable name="mod-result" select="($week - 1) mod $total"/>
    <xsl:value-of select="$mod-result + 1"/>
</xsl:template>

<xsl:template match="/">
    <!-- 输出标题加换行 -->
    <xsl:text>This week's menu:&#xA;</xsl:text>

    <!-- 选开胃菜 -->
    <xsl:variable name="appetizer-total" select="count(/menu/appetizers/dish)"/>
    <xsl:variable name="appetizer-pos">
        <xsl:call-template name="get-position">
            <xsl:with-param name="total" select="$appetizer-total"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="appetizer" select="/menu/appetizers/dish[position() = $appetizer-pos]"/>
    <xsl:text>- </xsl:text><xsl:value-of select="$appetizer"/>
    <xsl:text> $</xsl:text><xsl:value-of select="$appetizer/@price"/>
    <xsl:text>&#xA;</xsl:text>

    <!-- 选主菜 -->
    <xsl:variable name="entree-total" select="count(/menu/entrees/dish)"/>
    <xsl:variable name="entree-pos">
        <xsl:call-template name="get-position">
            <xsl:with-param name="total" select="$entree-total"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="entree" select="/menu/entrees/dish[position() = $entree-pos]"/>
    <xsl:text>- </xsl:text><xsl:value-of select="$entree"/>
    <xsl:text> $</xsl:text><xsl:value-of select="$entree/@price"/>
    <xsl:text>&#xA;</xsl:text>

    <!-- 选甜点,如需week=4时固定选最后一个,可在此处修改位置判断逻辑 -->
    <xsl:variable name="dessert-total" select="count(/menu/desserts/dish)"/>
    <xsl:variable name="dessert-pos">
        <xsl:call-template name="get-position">
            <xsl:with-param name="total" select="$dessert-total"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="dessert" select="/menu/desserts/dish[position() = $dessert-pos]"/>
    <xsl:text>- </xsl:text><xsl:value-of select="$dessert"/>
    <xsl:text> $</xsl:text><xsl:value-of select="$dessert/@price"/>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>

</xsl:stylesheet>
初学者提示
  • XSLT 1.0的RTF限制是最常见的新手坑,如果你一定要保留中间变量存节点的写法,需要引入处理器支持的node-set扩展函数(比如EXSLT的exsl:node-set),把RTF转成可查询的节点集后再做遍历,但这种写法依赖处理器兼容性,不如直接输出逻辑简单。
  • 输出纯文本时,所有换行、空格、前缀符号都要用<xsl:text>明确包裹,否则XSLT默认会压缩忽略无意义的空白。
  • 做循环索引计算时,一定要注意XPath的序列是从1开始计数的,可以根据自己的业务需求调整位置判断规则,比如需要到最后一个菜品后停止循环,就在mod结果为0且week不等于1时返回总数量即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 03:09:29