Tomsovi

  • Increase font size
  • Default font size
  • Decrease font size
Domů Honza Software Development XSLT Porovnávání textů v XSLT

Porovnávání textů v XSLT

E-mail Print PDF
There are no translations available.

Níže uvedený postup je vhodný pro porovnání dvou textů, které se liší pouze v rámci jednotlivých řádků, avšak řádky v textu nepřibývají, neubývají ani se nikam nepřesouvají.

Šablona využívá rekurzi, což některým parserům nedělá dobře. Např. Saxon.

Funguje však např. s MSXML - vyzkoušeno.

XML

<?xml version='1.0' encoding='windows-1250'?>
<?xml-stylesheet type="text/xsl" href="compare.xsl"?>
<texts>
<text.old>Hello world!
This is a sample text.

Sample text continues.
This is the end.
That's all folks!
</text.old>
<text.new>Hello world!
This is different text.

Sample text continues.
This is the END.
That's all folks!
</text.new>
</texts>

XSL

<?xml version="1.0"?>
<xsl:transform version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="cr">&#10;</xsl:variable>

<xsl:template match="texts">
<html>
<head>
        <meta http-equiv="Content-Language" content="cs"/>
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1250"/>
        <title>Comparing texts</title>
</head>
<body>
    <table border="1" style="border-collapse: collapse;">
            <tr>
                    <td>Old text</td>
                    <td>New text</td>
            </tr>
            <tr>
                    <td>
                        <pre><xsl:call-template name="PrintCompare">
                          <xsl:with-param name="lineNum" select="1"/>
                          <xsl:with-param name="old" select="text.new"/>
                          <xsl:with-param name="new" select="text.old"/>
                        </xsl:call-template></pre>
                    </td>
                    <td>
                        <pre><xsl:call-template name="PrintCompare">
                          <xsl:with-param name="lineNum" select="1"/>
                          <xsl:with-param name="old" select="text.old"/>
                          <xsl:with-param name="new" select="text.new"/>
                        </xsl:call-template></pre>
                    </td>
            </tr>
      </table>
</body>
</html>
</xsl:template>

<xsl:template name="PrintCompare">
    <xsl:param name="lineNum"/>
    <xsl:param name="old"/>
    <xsl:param name="new"/>
 
    <xsl:if test="$old">
       <span style="color:#ccc; margin-right: #ccc; border-right: black 1px solid"><xsl:call-template name="FixedWidth">
                       <xsl:with-param name="val" select="$lineNum"/>
                       <xsl:with-param name="len" select="4"/>
                       <xsl:with-param name="side" select="'begin'"/>
       </xsl:call-template></span>
       <xsl:if test="contains($old,$cr)">
         <xsl:if test="substring-before($old,$cr) = substring-before($new,$cr)">
            <span><xsl:value-of select="substring-before($new,$cr)"/></span>
         </xsl:if>
         <xsl:if test="substring-before($old,$cr) != substring-before($new,$cr)">
            <span style="background-color: yellow; color:red"><xsl:value-of select="substring-before($new,$cr)"/></span>
         </xsl:if>
         <br/>
         <xsl:call-template name="PrintCompare">
           <xsl:with-param name="lineNum" select="$lineNum+1"/>
           <xsl:with-param name="old" select="substring-after($old,$cr)"/>
           <xsl:with-param name="new" select="substring-after($new,$cr)"/>
         </xsl:call-template>
       </xsl:if>
       <xsl:if test="not(contains($old,$cr))">
           <xsl:if test="$old = $new">
              <span><xsl:value-of select="$new"/></span>
           </xsl:if>
           <xsl:if test="$old != $new">
              <span style="background-color: yellow; color:red"><xsl:value-of select="$new"/></span>
           </xsl:if>
       </xsl:if>
    </xsl:if>
</xsl:template>

<xsl:template name="FixedWidth">
    <xsl:param name="val"/>
    <xsl:param name="len"/>
    <xsl:param name="side"/>
    <xsl:if test="string-length($val) &lt; $len">
            <xsl:if test="$side = 'begin'">
                        <xsl:call-template name="FixedWidth">
                               <xsl:with-param name="val" select="concat(' ',$val)"/>
                               <xsl:with-param name="len" select="$len"/>
                               <xsl:with-param name="side" select="$side"/>
                        </xsl:call-template>
            </xsl:if><xsl:if test="$side != 'begin'">
                        <xsl:call-template name="FixedWidth">
                               <xsl:with-param name="val" select="concat($val,' ')"/>
                               <xsl:with-param name="len" select="$len"/>
                               <xsl:with-param name="side" select="$side"/>
                        </xsl:call-template>
            </xsl:if>
    </xsl:if>
    <xsl:if test="string-length($val) &gt;= $len">
            <xsl:value-of select="$val"/>
    </xsl:if>
</xsl:template>

</xsl:transform>

Výstup v HTML

Old text New text
   1Hello world!
2This is a sample text.
3
4Sample text continues.
5This is the end.
6That's all folks!
   1Hello world!
2This is different text.
3
4Sample text continues.
5This is the END.
6That's all folks!