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

F

for.fun

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>
 
F

for.fun

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>
 

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top