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

如何在XSL中对比XML节点值并高亮差异字符?

如何用XSLT对比XML中res1和res2的字符差异并在HTML中高亮显示

要实现你需要的字符级差异高亮,我们得在XSLT里自定义递归模板来逐个对比res1和res2的每个字符,把不同的部分用高亮样式包裹。因为你使用的是XSLT 1.0,没有内置的字符串拆分工具,所以我们用递归的方式来处理每个字符位置。

修改后的完整XSL代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <h2>Report</h2>
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="Message/DiffDetailMessage">
        <table border="2">
            <xsl:apply-templates select="TestCaseID"/>
            <tr>
                <td><b>Res1</b></td>
                <td>
                    <xsl:call-template name="compare-characters">
                        <xsl:with-param name="str1" select="res1"/>
                        <xsl:with-param name="str2" select="res2"/>
                        <xsl:with-param name="position" select="1"/>
                        <xsl:with-param name="is-res1" select="true()"/>
                    </xsl:call-template>
                </td>
            </tr>
            <tr>
                <td><b>Res2</b></td>
                <td>
                    <xsl:call-template name="compare-characters">
                        <xsl:with-param name="str1" select="res1"/>
                        <xsl:with-param name="str2" select="res2"/>
                        <xsl:with-param name="position" select="1"/>
                        <xsl:with-param name="is-res1" select="false()"/>
                    </xsl:call-template>
                </td>
            </tr>
        </table>
        <br/>
    </xsl:template>

    <xsl:template match="TestCaseID">
        <tr>
            <td><b>Test CaseID </b></td>
            <td><xsl:value-of select="."/></td>
        </tr>
    </xsl:template>

    <!-- 递归模板:对比两个字符串的每个字符,返回带高亮的文本 -->
    <xsl:template name="compare-characters">
        <xsl:param name="str1"/>
        <xsl:param name="str2"/>
        <xsl:param name="position"/>
        <xsl:param name="is-res1"/>

        <!-- 获取当前位置的字符 -->
        <xsl:variable name="char1" select="substring($str1, $position, 1)"/>
        <xsl:variable name="char2" select="substring($str2, $position, 1)"/>

        <!-- 判断是否需要高亮 -->
        <xsl:choose>
            <xsl:when test="$char1 != $char2 or ($position > string-length($str1) or $position > string-length($str2))">
                <!-- 高亮不同的字符或超出长度的部分 -->
                <span style="background-color: yellow; font-weight: bold;">
                    <xsl:value-of select="if ($is-res1) then $char1 else $char2"/>
                </span>
            </xsl:when>
            <xsl:otherwise>
                <!-- 相同字符直接输出 -->
                <xsl:value-of select="if ($is-res1) then $char1 else $char2"/>
            </xsl:otherwise>
        </xsl:choose>

        <!-- 递归处理下一个字符,直到两个字符串都处理完 -->
        <xsl:if test="$position <= string-length($str1) or $position <= string-length($str2)">
            <xsl:call-template name="compare-characters">
                <xsl:with-param name="str1" select="$str1"/>
                <xsl:with-param name="str2" select="$str2"/>
                <xsl:with-param name="position" select="$position + 1"/>
                <xsl:with-param name="is-res1" select="$is-res1"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

关键逻辑说明

  1. 递归对比模板compare-characters:

    • 用substring提取两个字符串对应位置的字符
    • 如果字符不同,或者其中一个字符串已到末尾(另一个还有剩余字符),就用黄色背景的<span>包裹该字符实现高亮
    • 递归调用自身处理下一个字符,直到两个字符串的所有字符都处理完毕
  2. res1/res2输出逻辑修改:
    不再直接输出原始文本,而是调用对比模板,通过is-res1参数控制输出res1或res2的字符,保证两边的差异位置对应高亮。

  3. 长度不一致处理:
    如果两个字符串长度不同,超出的部分会自动高亮,比如res2末尾的空格也会被识别为差异。

Java转换代码示例

你可以用Java标准API执行XML到HTML的转换:

import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.*;

public class XmlToHtmlConverter {
    public static void main(String[] args) throws Exception {
        Source xmlSource = new StreamSource(new File("your-input.xml"));
        Source xsltSource = new StreamSource(new File("your-transform.xsl"));
        
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer(xsltSource);
        
        Result result = new StreamResult(new File("output.html"));
        transformer.transform(xmlSource, result);
        
        System.out.println("HTML报告已生成!");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:12:52