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

xsl:key匹配失效:如何基于root.xml替换XHTML对应name/rate字段值

XSLT xsl:key配置错误导致字段替换为空问题解决方案

需求说明

输出与输入结构完全一致的XHTML,仅替换其中name、rate字段值为root.xml中对应的数据。

输入文件

主输入XHTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>PZBank</title>
  </head>
  <body>
    <table style="width:100%">
       <tr>
          <th align="left">Product #1</th>
          <th align="left">Product #2</th>
          <th align="left">Product #3</th>
       </tr>
       <tr>
          <td name="name0">Whiz-bang</td>
          <td name="name1">Ulitmate</td>
          <td name="name2">Killer</td>
       </tr>
       <tr>
          <td name="rate0">2.09</td>
          <td name="rate1">1.99</td>
          <td name="rate2">3.19</td>
       </tr>
    </table>
  </body>
</html>

数据源 root.xml

<root>
  <dbu>
    <product ord="0">
      <name>Amazing</name>
      <rate>4.5</rate>
    </product>
  </dbu>
  <dbu>
    <product ord="1">
      <name>Incredible</name>
      <rate>6.6</rate>
    </product>
  </dbu>
</root>

原错误XSLT的问题点

原代码的xsl:key配置完全不符合索引规则:

  1. krate的use属性写了全路径/root/dbu/product[@ord],没有取到对应product的ord属性值作为索引键
  2. kname的use属性取@ord,但name节点本身没有ord属性,该属性在name的父节点product上,所以无法匹配到任何结果

修正后完整XSLT代码

<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">
  <xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8" include-content-type="no"/>
  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:variable name="rooter" select="document('root.xml')"/>

  <!-- 修正key定义:use取父节点product的ord属性作为索引键 -->
  <xsl:key name="krate" match="product/rate" use="../@ord"/>
  <xsl:key name="kname" match="product/name" use="../@ord"/>

  <xsl:template match="td[starts-with(@name,'rate')]/text()">
    <xsl:variable name="ordv" select="substring-after(../@name,'rate')"/>
    <!-- 优先取匹配到的rate值,没有匹配则保留原值 -->
    <xsl:value-of select="(key('krate',$ordv, $rooter), .)[1]"/>
  </xsl:template>

  <xsl:template match="td[starts-with(@name,'name')]/text()">
    <!-- 优先取匹配到的name值,没有匹配则保留原值 -->
    { (key('kname', substring-after(../@name, 'name'), $rooter), .)[1] }
  </xsl:template>

</xsl:stylesheet>

转换效果说明

  • ord=0的单元格:name替换为Amazing,rate替换为4.5
  • ord=1的单元格:name替换为Incredible,rate替换为6.6
  • ord=2的单元格:root.xml中无对应配置,保留原有值不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 04:12:02