This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Combining XML data


Tom,

>Are there any examples of the usage of document().  I too am trying to
>merge and report the differences of two similarly formatted XML documents. 
>Perhaps I'm still thinking the wrong way but I thought it would be
>necessary to store two context nodes (one from each document) so that all
>instances of elements in one document but not the other could be examined
>as well as comparing the contents of the same node in each document.

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).

Probably posting your documents and giving more details about the possible
similarities and differences would help give more relevant examples.

Hope that helps anyway,

Jeni

Dr Jeni Tennison
Epistemics Ltd, Strelley Hall, Nottingham, NG8 6PE
Telephone 0115 9061301 • Fax 0115 9061304 • Email
jeni.tennison@epistemics.co.uk



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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]