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

XSLT2中如何比较子节点并高亮设备历史数据差异?

用XSLT 2.0对比设备历史数据并高亮差异

嘿,作为XSLT新手,你这个需求其实可以通过拆分字符串、对比相邻节点值来实现。咱们一步步来改造你的代码,实现高亮变更值的效果:

首先,你的原XML里两个<Details>的DeviceInfo只有id2的值不同,我们需要把每个键值对拆出来,和前一条记录的对应值对比,不一样的就高亮(比如加粗)。

核心思路

  • 升级XSLT版本到2.0(你的原代码是1.0,要用上2.0的字符串拆分函数)
  • 把DeviceInfo的字符串拆成独立的键值对(比如Id1:459800800691拆成键Id1和值459800800691)
  • 对每个键值对,和前一个<Details>节点的对应值做比较
  • 若值不同,用自定义CSS样式或<b>标签高亮显示

修改后的完整XSLT代码

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 主模板,生成HTML结构 -->
  <xsl:template match="/DeviceHistory">
    <html>
      <head>
        <!-- 自定义高亮样式,比原生<b>更灵活 -->
        <style>
          .highlight { font-weight: bold; color: #dc3545; }
          table { border-collapse: collapse; margin: 10px 0; }
          td { padding: 8px; border: 1px solid #ddd; }
        </style>
      </head>
      <body>
        <xsl:apply-templates select="Part"/>
      </body>
    </html>
  </xsl:template>

  <!-- 处理Part节点,生成外层表格 -->
  <xsl:template match="Part">
    <h3>设备历史:<xsl:value-of select="@Name"/></h3>
    <table border='1'>
      <tr>
        <xsl:for-each select="Details">
          <td class='FRUVal' valign='middle' width='380'>
            <table>
              <tr><td><strong>日期:</strong><xsl:apply-templates select="Date"/></td></tr>
              <tr>
                <td>
                  <strong>设备信息:</strong>
                  <!-- 按空格拆分DeviceInfo为单个键值项 -->
                  <xsl:for-each select="tokenize(DeviceInfo, '\s+')">
                    <!-- 把每个键值项拆成键和值(按冒号分割) -->
                    <xsl:variable name="currentKey" select="tokenize(., ':')[1]"/>
                    <xsl:variable name="currentValue" select="tokenize(., ':')[2]"/>
                    
                    <!-- 获取前一个Details节点中对应键的值 -->
                    <xsl:variable name="prevValue">
                      <xsl:if test="position() &gt; 1">
                        <xsl:value-of select="tokenize(preceding-sibling::Details[1]/DeviceInfo, '\s+')[tokenize(., ':')[1] = $currentKey]/tokenize(., ':')[2]"/>
                      </xsl:if>
                    </xsl:variable>
                    
                    <!-- 输出逻辑:第一个节点直接输出;后续节点对比值,不同则高亮 -->
                    <xsl:value-of select="$currentKey"/>:
                    <xsl:choose>
                      <xsl:when test="position() = 1">
                        <xsl:value-of select="$currentValue"/>
                      </xsl:when>
                      <xsl:when test="$currentValue != $prevValue">
                        <span class="highlight"><xsl:value-of select="$currentValue"/></span>
                      </xsl:when>
                      <xsl:otherwise>
                        <xsl:value-of select="$currentValue"/>
                      </xsl:otherwise>
                    </xsl:choose>
                    <!-- 键值对之间加空格分隔 -->
                    <xsl:if test="position() != last()"> </xsl:if>
                  </xsl:for-each>
                </td>
              </tr>
            </table>
          </td>
        </xsl:for-each>
      </tr>
    </table>
  </xsl:template>
</xsl:stylesheet>

代码关键点解释

  • tokenize()函数:XSLT2.0新增的字符串拆分工具,这里用\s+匹配任意空格拆分整个DeviceInfo,再用:拆分单个键值项,轻松提取键和值。
  • preceding-sibling::Details[1]:精准获取当前<Details>的前一个兄弟节点,用来提取历史数据做对比。
  • 高亮逻辑:第一个<Details>没有历史数据直接输出;后续节点对比当前值和历史值,不同则应用highlight样式,视觉上清晰区分变更内容。
  • 样式优化:加入了基础CSS让表格更美观,高亮用红色加粗,你可以根据需求调整颜色、字体等样式。

渲染效果

用你的XML测试时,第二个<Details>里的id2:000008会显示为红色加粗样式,和第一个的id2:000007形成明显对比,完美体现数据变更。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:15:38