Re: [xsl] Stuck with Jeni's Logic...Help me out..!!

Subject: Re: [xsl] Stuck with Jeni's Logic...Help me out..!!
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sat, 6 Apr 2002 17:36:18 +0100
Hi Sachi,

> My need is to get a different of A (xml file) and B (xml File) and
> then get C (as xml file).
>
> In the similar way b.xml will be there. Based on VersionID I need to
> compare A wish B and put into C elements of A which is not found in
> B.xml.

So you need to copy the RecipeVersion elements from A if there isn't a
RecipeVersion element in B with the same VersionID.

Since you're dealing with two documents, I'd hold the RecipeVersions
document element in each in a global variable so that you can get hold
of it easily:

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

Since you want to get hold of RecipeVersion elements based on their
VersionID, I'd create a key to index the RecipeVersion elements by
their VersionID:

<xsl:key name="recipes" match="RecipeVersion" use="@VersionID" />

You want to create a RecipeVersions element:

<xsl:template match="/">
  <RecipeVersions>
    ...
  </RecipeVersions>
</xsl:template>

and for its content, go over the RecipeVersion elements in A:

<xsl:template match="/">
  <RecipeVersions>
    <xsl:for-each select="$A/RecipeVersion">
      ...
    </xsl:for-each>
  </RecipeVersions>
</xsl:template>

Store that RecipeVersion in a variable so that you can get at it
later:

<xsl:template match="/">
  <RecipeVersions>
    <xsl:for-each select="$A/RecipeVersion">
      <xsl:variable name="a" select="." />
      ...
    </xsl:for-each>
  </RecipeVersions>
</xsl:template>

Then swap context to B.xml

<xsl:template match="/">
  <RecipeVersions>
    <xsl:for-each select="$A/RecipeVersion">
      <xsl:variable name="a" select="." />
      <xsl:for-each select="$B">
        ...
      </xsl:for-each>
    </xsl:for-each>
  </RecipeVersions>
</xsl:template>

and search it for RecipeVersions whose VersionID is the same as $a's
VersionID, using the key:

<xsl:template match="/">
  <RecipeVersions>
    <xsl:for-each select="$A/RecipeVersion">
      <xsl:variable name="a" select="." />
      <xsl:for-each select="$B">
        ... key('recipes', $a/VersionID) ...
      </xsl:for-each>
    </xsl:for-each>
  </RecipeVersions>
</xsl:template>

If you don't manage to find RecipeVersion element in B, then you want
to copy $a:

<xsl:template match="/">
  <RecipeVersions>
    <xsl:for-each select="$A/RecipeVersion">
      <xsl:variable name="a" select="." />
      <xsl:for-each select="$B">
        <xsl:if test="not(key('recipes', $a/VersionID))">
          <xsl:copy-of select="$a" />
        </xsl:if>
      </xsl:for-each>
    </xsl:for-each>
  </RecipeVersions>
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Current Thread