Question

I have two XML-files similar to this:

1.

<data>
   <object ID="1">
      <ID>1</ID>
      <name>abc</name>
      <weight>50</weight>
   </object>
   <object ID="2">
      <ID>2</ID>
      <name>def</name>
      <weight>75</weight>
   </object>
</data>

2.

<data>
   <object ID="2">
      <ID>2</ID>
      <name>def</name>
      <weight>75</weight>
   </object>
   <object ID="3">
      <ID>3</ID>
      <name>ghi</name>
      <weight>100</weight>
   </object>
</data>

And now I want to compare them. Either with an additional element (something like both) or a new files (in_both_files.xml, only_in_file1.xml, only_in_file2.xml). I know, XSLT is not the best for this quest, i am missing PHP/SQL... What would be the best way to solve this problem? I already searched for a solution, but most people seem to be happy to just merge it. My idea was to give every object the ID as attribut and then go through the first file and use document() and key() to look for the same object in the other file. Is this good/even possible? Didn't work by now, and i don't know, whether it's the right way.

Edit: This is for a stocktaking. One XML-file is the objects we have, according to the system and the other one what is really in the depot. So if one object appears on both lists, they have the absolute same ID, name, weight, etc. But the ID is the only thing, thats absolute uniquefor each object (but of course should be in both files). So I need to know, which object are in the depot but not in the system, so I can import them, and which ones are in the system, but not in the depot, and so have to be labeld as "lost".

So just merging them, won't help...

A result like

only_in_system.xml
<data>
   <object>
      <ID>1</ID>
      <name>abc</name>
      <weight>50</weight>
   </object>
</data>

only_in_depot.xml
<data>
   <object>
      <ID>3</ID>
      <name>ghi</name>
      <weight>100</weight>
   </object>
</data>

(additional) everything_is_ok.xml
<data>
   <object>
      <ID>2</ID>
      <name>def</name>
      <weight>75</weight>
   </object>
</data>

would be nice! Also more individual transormations could be used (and i think, have to) in a row!

Was it helpful?

Solution

So if one object appears on both lists, they have the absolute same ID, name, weight, etc.

Okay then, that really makes it rather simple:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:variable name="file2" select="document('file2.xml')" />

<xsl:variable name="IDs1" select="/data/object/ID" />
<xsl:variable name="IDs2" select="$file2/data/object/ID" />

<xsl:template match="/data">
<result>
    <data desc="only in file1">
        <xsl:apply-templates select="object[not(ID=$IDs2)]"/>
    </data>
    <data desc="only in file2">
        <xsl:apply-templates select="$file2/data/object[not(ID=$IDs1)]"/>
    </data>
    <data desc="in both files">
        <xsl:apply-templates select="object[ID=$IDs2]"/>
    </data>
</result>
</xsl:template>

<xsl:template match="object">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top