[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Merging XML

Subject: Re: Merging XML
From: Tom Mullen <Tom.Mullen@xxxxxxxxxxx>
Date: Fri, 04 Aug 2000 14:20:55 +0000 (GMT)
xsl string comparison ignore whitespace
Josh,

using the examples you gave:

>1.xml:
>  <A>
>  <B name="123">
>     <C>
>      <D>
>       <E>val 1</E>
>      </D>
>     </C>
>     <G>1</G>
>  </B>
>  </A>
>2.xml:
>  <A>
>  <B name="123">
>    <H>
>      <F>
>         Val3
>      </F>
>    </H>
>    <C>
>      <D>
>       <E> Val2 </E>
>      </D>
>    </C>
>  </B>
>  </A>
>
>
>If I rearrange the order to put <A><B><C>.. instead of <A><B><H>..
>it works.
>


Then the following xsl doc treats both 2) and its rearranged form the same.
 A few warnings:

1) Anybody who knows anything about XSL will recognise this as being
written by a newbie. (any comments at all on it would be most welcome)
2) I think there needs to be some form of ignore whitespace setting (I get
that there is a difference in B when there isn't)
3) This xsl only works with the format of the XML documents above.  I think
a generic solution would be an order of magnitude more difficult (anybody 
prepared to take up the gauntlet?).
4) Only a difference html is produced, I haven't got round to installing
<xsl:copy> and/or <xsl:copy-of> at the appropriate points.  However, this
example should explain the approach a little more clearly.
5) Apologies in advance for the lack of comments


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

<xsl:param name="oldfile" />

<xsl:variable name="old" select="document($oldfile)" />
<xsl:variable name="new" select="/" />


<xsl:template match="/A">
<html>
<head><title>Comparison</title></head>
<body>
<h1>Comparison</h1>
<xsl:comment><xsl:value-of select="$new/"/></xsl:comment>
<xsl:comment><xsl:value-of select="$old/"/></xsl:comment>
<xsl:comment><xsl:value-of select="$oldfile"/></xsl:comment>
<xsl:call-template name="compall">
    <xsl:with-param name="new" select="$new" />
    <xsl:with-param name="old" select="$old" />
</xsl:call-template>
</body>
</html>
</xsl:template>

<xsl:template name="compall">
  <xsl:param name="old" />
  <xsl:param name="new" />

  <xsl:variable name="oldval" select="$old/text()"/>
  <xsl:variable name="newval" select="$new/text()"/>
  <xsl:if test="not((string-length($oldval)=string-length($newval)) and
contains($oldval,$newval))">
    <xsl:comment>different vals</xsl:comment>
    <xsl:variable name="oldname" select="name($old)" />
    <xsl:variable name="newname" select="name($new)" />
    <p>Altered NEW:<xsl:value-of select="$newname"/>=<xsl:value-of
select="$newval"/></p>
    <p>Altered OLD:<xsl:value-of select="$oldname"/>=<xsl:value-of
select="$oldval"/></p>
  </xsl:if>

  <xsl:call-template name="list-additional">
    <xsl:with-param name="head">Added:</xsl:with-param>
    <xsl:with-param name="more" select="$new" />
    <xsl:with-param name="less" select="$old" />
  </xsl:call-template>

  <xsl:call-template name="list-additional">
    <xsl:with-param name="head">Removed:</xsl:with-param>
    <xsl:with-param name="more" select="$old" />
    <xsl:with-param name="less" select="$new" />
  </xsl:call-template>

  <xsl:call-template name="list-compare">
    <xsl:with-param name="old" select="$old" />
    <xsl:with-param name="new" select="$new" />
  </xsl:call-template>

</xsl:template>


<xsl:key name="logs" match="B" use="@name" />

<xsl:template name="list-additional">
  <xsl:param name="head" />
  <xsl:param name="more" />
  <xsl:param name="less" />
  <ul>
  <xsl:if test="$more/B">
  <xsl:for-each select="$more/B">
    <xsl:variable name="item" select="." />
    <!-- select the 'less' document so that the key indexes into that
         document -->
    <xsl:for-each select="$less">
    <xsl:if test="not(key('logs', $item/@name))">
        <xsl:comment><xsl:value-of select="$item"/></xsl:comment>
        <li><xsl:value-of select="$head"/><xsl:apply-templates
select="$item" mode="describe" /></li>
      </xsl:if>
    </xsl:for-each>
  </xsl:for-each>
  </xsl:if>
  <xsl:for-each select="$more/*"> 
    <xsl:variable name="item" select="." />
    <xsl:variable name="itemname" select="name(.)" />
    <xsl:choose>
      <xsl:when test="self::B"/>
      <xsl:otherwise>
 <xsl:comment>looking for <xsl:value-of select="$itemname"/></xsl:comment>
        <xsl:choose>
	  <xsl:when test="$less/*[name()=name($item)]"/>
          <xsl:otherwise>
            <xsl:comment><xsl:value-of select="$item"/></xsl:comment>
            <li><xsl:value-of select="$head"/><xsl:apply-templates
select="$item" mode="describe" /></li>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
  </ul>
</xsl:template>

<xsl:template name="list-compare">
  <xsl:param name="old" />
  <xsl:param name="new" />
 <xsl:variable name="oldname" select="name($old)" />
 <xsl:variable name="newname" select="name($new)" />
  <ul>
  <xsl:if test="$old/B">
  <xsl:for-each select="$old/B">
    <xsl:variable name="old2" select="." />
    <xsl:for-each select="$new">
      <xsl:if test="key('logs', $old2/@name)">
	<xsl:variable name="new2" select="key('logs', $old2/@name)"/>
          <xsl:call-template name="compall">
            <xsl:with-param name="new" select="$new2" />
            <xsl:with-param name="old" select="$old2" />
          </xsl:call-template>
      </xsl:if>
    </xsl:for-each>
  </xsl:for-each>
  </xsl:if>
  <xsl:for-each select="$old/*"> 
    <xsl:variable name="old2" select="." />
    <xsl:variable name="old2name" select="name(.)" />
    <xsl:choose>
      <xsl:when test="self::B"/>
      <xsl:otherwise>
 <xsl:comment>looking for <xsl:value-of select="$old2name"/></xsl:comment>
	<xsl:variable name="new2" select="$new/*[name()=$old2name]"/>
	<xsl:if test="$new/*[name()=name($old2)]">
	<xsl:variable name="newval" select="$new2/self::text()"/>
	<xsl:variable name="oldval" select="$old2/self::text()"/>
 	<xsl:comment>New val=<xsl:value-of select="$newval"/>Old
val=<xsl:value-of select="$oldval"/></xsl:comment>
        <xsl:call-template name="compall">
          <xsl:with-param name="new" select="$new2" />
          <xsl:with-param name="old" select="$old2" />
        </xsl:call-template>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
  </ul>
</xsl:template>

<xsl:template match="*" mode="describe">
  <xsl:value-of select="name()" /><xsl:text>=</xsl:text><xsl:value-of
select="text()" />
</xsl:template>

<xsl:template match="B" mode="describe">
   <xsl:text>B-</xsl:text><xsl:value-of select="@name" />
</xsl:template>

</xsl:stylesheet>



Thanks

Tom

-----------------------------------------------------------------
        Visit our Internet site at http://www.reuters.com

Any views expressed in this message are those of  the  individual
sender,  except  where  the sender specifically states them to be
the views of Reuters Ltd.


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread
  • Merging XML
    • Roshan Sharma - Thu, 03 Aug 2000 20:40:40 GMT
      • Tom Mullen - Fri, 04 Aug 2000 08:48:58 +0000 (GMT)
      • Tom Mullen - Fri, 04 Aug 2000 14:20:55 +0000 (GMT) <=
      • <Possible follow-ups>
      • Oliver Becker - Mon, 7 Aug 2000 10:08:06 +0200 (MET DST)
        • Tom Mullen - Tue, 08 Aug 2000 13:09:59 +0000 (GMT)
      • Oliver Becker - Tue, 8 Aug 2000 19:30:19 +0200 (MET DST)

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.