Looking for a XML comparison tool which does not take care of the nodes' order ?

Discussion in 'XML' started by for.fun@laposte.net, Sep 16, 2005.

  1. Guest

    Hi everybody,


    I am looking for a XML comparison tool (I do not mean a standard
    char-by-char diff tool but a tool which understand XML syntax)

    More precisely, I can have serveral XML structures organized
    differently. The XML nodes can store the same data but be organized
    differently => in such a case, I would like the diff tool to tell me
    that both XML files are identicals.

    As far as I am concerned, XML1 and XML2 are identicals (please look at
    the sample below).

    => Do you know a command line tool which is able to do this ?


    Thanks in advance.


    Sample :
    ------

    XML 1:

    <grand-father>
    abraham

    <father1>
    sean

    <child1>
    arthur
    </child1>

    <child2>
    john
    </child2>

    </father1>


    <father2>
    michael

    <child1>
    peter
    </child1>

    </father2>

    </grand-father>



    XML 2:

    <grand-father>
    abraham
    <father2>michael<child1>peter</child1></father2>
    <father1>sean<child2>john</child2><child1>arthur</child1></father1>
    </grand-father>
     
    , Sep 16, 2005
    #1
    1. Advertising

  2. pantagruel Guest

    1. Advertising

  3. Guest

    , Sep 17, 2005
    #3
  4. Guest

    I finally quickly wrote the following style sheet (look after these
    lines) which flatten the XML input.
    I applied the stylesheet to file1/file2, sorted the 2 files and then
    applied a classical diff on the 2 files.

    Thanks to the flatten format, the 'diff' tell us exactly where the
    differences are and there is no need to spend some money for a tool !


    -------------------------- Flattening style sheet
    --------------------------

    <?xml version='1.0'?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:eek:utput method="text"/>

    <xsl:variable name="newline">
    <xsl:text>
    </xsl:text>
    </xsl:variable>

    <xsl:template match="/">

    <!-- Walk the input XML tree starting from the root node -->

    <xsl:call-template name="walk">
    <xsl:with-param name="leftNode" select="."/>
    <xsl:with-param name="rightNodes" select="./following-sibling::*"/>
    <xsl:with-param name="currentPath"></xsl:with-param>
    </xsl:call-template>

    </xsl:template>

    <xsl:template name="walk">

    <xsl:param name="leftNode"/>
    <xsl:param name="rightNodes"/>
    <xsl:param name="currentPath"/>


    <!-- Walk the left node while we have some children or some token's
    attributes to process -->

    <xsl:choose>

    <xsl:when test="boolean($leftNode/child::*) or
    (not(boolean($leftNode/child::*)) and
    boolean(count($leftNode/@*)!=0))">

    <!-- Prepare the attributes' string before printing it to the
    output -->

    <xsl:variable name="leftNodeAttributes">
    <xsl:if test="count($leftNode/@*)!=0">
    <xsl:text>{</xsl:text>
    <xsl:for-each select="$leftNode/@*">
    <xsl:text>@</xsl:text><xsl:value-of
    select="name()"/>="<xsl:value-of select="."/>"<xsl:text/>
    <xsl:if test="not(position()=last())"><xsl:text>
    </xsl:text></xsl:if>
    </xsl:for-each>
    <xsl:text>}</xsl:text>
    </xsl:if>
    </xsl:variable>


    <!-- Concatenate the iteration's node path to the current node
    path -->

    <xsl:variable name="newPath" select="concat(concat($currentPath,
    concat('/', normalize-space(name($leftNode)))), $leftNodeAttributes)"/>


    <!-- Walk down one step -->

    <xsl:call-template name="walk">
    <xsl:with-param name="leftNode"
    select="$leftNode/child::*[1]"/>
    <xsl:with-param name="rightNodes"
    select="$leftNode/child::*[1]/following-sibling::*"/>
    <xsl:with-param name="currentPath" select="$newPath"/>
    </xsl:call-template>

    </xsl:when>


    <!-- If we reached a leaf then output the full node path -->

    <xsl:eek:therwise>
    <xsl:value-of select="$currentPath"/>
    <xsl:if test="boolean($leftNode)">/<xsl:value-of
    select="name($leftNode)"/>/<xsl:value-of
    select="normalize-space($leftNode)"/></xsl:if>
    <xsl:value-of select="$newline"/>
    </xsl:eek:therwise>

    </xsl:choose>


    <!-- Walk the right nodes while there are some siblings to process
    -->

    <xsl:if test="boolean($rightNodes)">

    <!-- Walk to the next sibling on the same level -->

    <xsl:call-template name="walk">
    <xsl:with-param name="leftNode" select="$rightNodes[1]"/>
    <xsl:with-param name="rightNodes"
    select="$rightNodes[1]/following-sibling::*"/>
    <xsl:with-param name="currentPath" select="$currentPath"/>
    </xsl:call-template>

    </xsl:if>

    </xsl:template>

    </xsl:stylesheet>
     
    , Sep 19, 2005
    #4
  5. gulin

    Joined:
    Jun 9, 2008
    Messages:
    1
    gulin, Jun 9, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. gavnosis
    Replies:
    0
    Views:
    525
    gavnosis
    Aug 2, 2003
  2. Johnny Ooi

    Looking A Nodes From Within Nodes

    Johnny Ooi, Nov 13, 2004, in forum: XML
    Replies:
    10
    Views:
    657
    Johnny Ooi
    Nov 14, 2004
  3. newbie
    Replies:
    2
    Views:
    296
    newbie
    Jul 27, 2007
  4. xiang chen
    Replies:
    2
    Views:
    616
    The Ghost in The Machine
    May 14, 2011
  5. Steve Mauldin
    Replies:
    0
    Views:
    134
    Steve Mauldin
    Feb 6, 2004
Loading...

Share This Page