[xsl] Merging XML data from different files

Subject: [xsl] Merging XML data from different files
From: mjyoungblut@xxxxxxx
Date: Fri, 19 Jan 2001 15:19:19 -0600
My question is regarding the very bottom of the text that I found on the
FAQ page for the document( ) funtion - the response for 'Combining XML data
from different files'(the response is shown below).

I have multiple XML files, and I am able to combine the primary and the
secondary files according to an 'ID' in the first.  There are extra 'IDs'
in the secondary files that I wish to join as well - How do I go about
this??

     My question requires some insight to this quote taken from the bottom
of the response:
          ..."You'd have to  do something a bit more complicated if you
wanted to do the comparison the other way as well (e.g. identify the
elements that       exist in document2 but not in document1)."

Thank you for your help,
     Matt Youngblut


-------------------------------------------------------Previous
Response----------------------------------------------------
16. Combining XML data from different files

   Jeni Tennison

   One of the difficulties lies in identifying the 'same node' in two
different documents. I can think of two main ways of saying that two nodes
in different
   documents are the 'same node':

   1. they are in the same position (relative to other nodes)
   2. they have the same identifier

   How you go about merging and reporting on differences between the two
XML documents really depends on which of these can be used.

   If it is the first (same position), then you're right that you have to
keep track of the 'context node' in the two documents. It's easy to keep
track of one of the
   context nodes (the processor does that for you), but the other will have
to be passed from template to template, making especially sure that it is
never lost
   through the use of the built-in templates. So, with document1.xml and
document2.xml as the two documents, and document1.xml being the input,
something
   like:

   <xsl:template match="/">
     <xsl:variable name="doc2node" select="document('document2.xml')" />
     <xsl:for-each select="*">
       <xsl:variable name="index" select="position()" />
       <xsl:apply-templates select=".">
         <xsl:with-param name="doc2node" select="$doc2node/*[position() =
   $index]" />
       </xsl:apply-templates>
     </xsl:for-each>
   </xsl:template>

   <xsl:template match="*">
     <xsl:param name="doc2node" />
     <!-- do your element comparison here -->
     <xsl:for-each select="@*">
       <xsl:variable name="name" select="name()" />
       <xsl:apply-templates select=".">
         <xsl:with-param name="doc2node" select="$doc2node/@*[name()
= $name]" />
       </xsl:apply-templates>
     </xsl:for-each>
     <xsl:for-each select="*">
       <xsl:variable name="index" select="position()" />
       <xsl:apply-templates select=".">
         <xsl:with-param name="doc2node" select="$doc2node/*[position() =
   $index]" />
       </xsl:apply-templates>
     </xsl:for-each>
   </xsl:template>

   <xsl:template match="@*">
     <xsl:param name="doc2node" />
     <!-- do your attribute comparison here -->
   </xsl:template>

   If, on the other hand, you have a structure in which elements can be
individually identified somehow, then you don't have to keep track of where
you are in the
   second document all the time - you can just index into it to get the
node to compare. So, say you had two documents, each of which had a load of
elements
   with @id attributes on them, you could have something like:

   <xsl:key name="ided-nodes" match="*[@id]" use="@id" />

   <xsl:template match="*[@id]">
     <xsl:variable name="doc1node" select="." />
     <xsl:for-each select="document('document2.xml')">
       <xsl:variable name="doc2node" select="key('ided-nodes',
$doc1node/@id)" />
       <!-- do your comparison between $doc1node and $doc2node here -->
     </xsl:for-each>
   </xsl:template>

   Both of these approaches take document1.xml as the primary document - it
is specified as the input and is used as the basis of the comparison. You'd
have to  do something a bit more complicated if you wanted to do the
comparison the other way as well (e.g. identify the elements that exist in
document2 but not in document1).









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


Current Thread