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,

>Here's where my original question came in.  It would be useful (possibly
>necessary) that comparisons are made of:
>
>a) the items selected or used between different versions/release
>b) the items currently deployed on a target machine compared against the
>information obtained at the time of release (for regular verification)
>c) the items currently extracted for release (to check that someone hasn't
>slipped in a change since the release package was made)

So, you have separate XML documents for each version/release, each of which
is of the form that you give.  Is the list of currently deployed items on a
target machine, and those currently extracted for release also available in
XML?  Without some kind of extension element/function, XSLT can't be used
to query the hard drive to find out what's actually there.  Because I'm
confused about how you were going to manage this, I'll just concentrate on
comparing two XML documents of the type that you've provided to see what
varies between the versions/releases.

(I'm afraid that I'm no expert on configuration management software, so
it's a little difficult for me to translate between your abstract
descriptions and the particular XML that you're using, so please bear with
me.)

First, set up a parameter to specify the XML file for the old release with
which you want to compare the new release:

<xsl:param name="oldfile" />

And then set up two variables that hold the document nodes for the two
files, so that within the code you can refer to the new and old releases in
the same way:

<xsl:variable name="old" select="document($oldfile)" />
<xsl:variable name="new" select="/" />

Now, declare a template that organises the comparison, on the root node of
the input file:

<xsl:template match="/">
<html>
<head><title>Release Comparison</title></head>
<body>
<h1>Release Comparison</h1>
<p>
  Old release: <xsl:apply-templates
                 select="$old/RELEASEDOC/RELEASESELECTION" />
</p>
<p>
  New release: <xsl:apply-templates
                 select="$new/RELEASEDOC/RELEASESELECTION" />
</p>

<h2>Items Added</h2>
<xsl:call-template name="list-additional">
  <xsl:with-param name="more" select="$new" />
  <xsl:with-param name="less" select="$old" />
</xsl:call-template>

<h2>Items Removed</h2>
<xsl:call-template name="list-additional">
  <xsl:with-param name="more" select="$old" />
  <xsl:with-param name="less" select="$new" />
</xsl:call-template>

<h2>Items Altered</h2>
<xsl:apply-templates select="$new/RELEASEDOC/CONFIGUREDITEM"
                     mode="compare" />

</body>
</html>
</xsl:template>

This template simply outputs the version of the release, but you could add
more details if you want:

<xsl:template match="RELEASESELECTION">
  Version <xsl:value-of select="VERSION" />
</xsl:template>

In terms of comparing the items themselves, each of the items is identified
by their name (defined by the content of the child NAME element).  So, it's
useful to have a key to help index into those:

<xsl:key name="items" match="CONFIGUREDITEM" use="NAME" />

The 'list-additional' template takes two arguments:
* 'more' - the document with extra items in
* 'less' - the document with less items in
This is so that we can use the same template both to list the items that
have been added in the new release and those that have been removed in the
new release.  For added items, 'more' is the $new document and 'less' the
$old document; for removed items, vice versa:

<xsl:template name="list-additional">
  <xsl:param name="more" />
  <xsl:param name="less" />
  <ul>
  <!-- cycle through each item in the 'more' document -->
  <xsl:for-each select="$more/RELEASEDOC/CONFIGUREDITEM">
    <xsl:variable name="item" select="." />
    <!-- select the 'less' document so that the key indexes into that
         document -->
    <xsl:for-each select="$less">
      <xsl:if test="not(key('items', $item/NAME))">
        <li><xsl:apply-templates select="$item" mode="describe" /></li>
      </xsl:if>
    </xsl:for-each>
  </xsl:for-each>
  </ul>
</xsl:template>

The template that is used to give a description of the item simply gives
its name, but you could add more details if you want:

<xsl:template match="CONFIGUREDITEM" mode="describe">
  <xsl:value-of select="NAME" />
</xsl:template>

Finally, this template does the comparison between items.  It is applied to
any CONFIGUREDITEM within the $new document, which means that some of the
time it will be applied to an item that doesn't exist in the $old document.
 So, we check that such an item exists in the $old document before doing
the comparison.  The comparison itself currently only checks the version of
the items in the two different files, but you could add more checks if you
want.

<xsl:template match="CONFIGUREDITEM" mode="compare">
  <xsl:variable name="newitem" select="." />
  <xsl:for-each select="$old">
    <xsl:variable name="olditem" select="key('items', $newitem/NAME)" />
    <xsl:if test="$olditem">
      <h3><xsl:value-of select="$newitem/NAME" /></h3>
      <dl>
        <dt>Version</dt>
        <dd>
          <xsl:choose>
            <xsl:when test="$olditem/RELEASESELECTION/VERSION !=
$newitem/RELEASESELECTION/VERSION">
              Changed: New version = <xsl:value-of
select="$newitem/RELEASESELECTION/VERSION" />;
                       Old version = <xsl:value-of
select="$olditem/RELEASESELECTION/VERSION" />
            </xsl:when>
            <xsl:otherwise>
              No Change
            </xsl:otherwise>
          </xsl:choose>
        </dd>
      </dl>
    </xsl:if>
  </xsl:for-each>
</xsl:template>

I hope that this at least gives you some ideas about achieving what you
want to achieve even if it's not precisely what you want.  Please post
again if there are any remaining issues or any bits of this post that
aren't clear - I've tried to keep it fairly short :)

Cheers,

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]