Re: [xsl] Testing if something is not there

Subject: Re: [xsl] Testing if something is not there
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 6 Nov 2001 11:27:20 +0000
Hi Jim,

> I can achieve this result using xsl:key and the key() function.
> While difficult to grok, it is VERY FAST. Now the kicker. Not every
> "Test" is run on every "Site" (not every "Test/FullName" needs to
> appear under every "BuildStamp"). What I really want to do is "fill
> out" the Test elements, so that every BuildName/Site appears inside
> of every Test element. If the Site did not run the Test, then the
> "Status" will be set to "NA".

If you want to make every BuildName/Site appear, then you need to
iterate over every BuildName/Site. You should still use the key to get
hold of the names of the tests (unless you have them listed
elsewhere):

  <xsl:variable name="BuildStamps" select="BuildStamp" />
  <xsl:for-each select="$BuildStamps/Testing/Tests/Test
                          [count(.|key('TestNames', FullName)[1]) = 1]">
    <xsl:variable name="TestName" select="FullName" />
    <Test>
      <Name><xsl:value-of select="$TestName" /></Name>
      ...
    </Test>
  </xsl:for-each>

Then you can iterate over each of the BuildStamp elements to work out
whether the site carries out the test or not. If it does, then you add
the Result with a Status from the relevant Test/Result. If it doesn't,
then the Status takes the value NA:

  <xsl:variable name="BuildStamps" select="BuildStamp" />
  <xsl:for-each select="$BuildStamps/Testing/Tests/Test
                          [count(.|key('TestNames', FullName)[1]) = 1]">
    <xsl:variable name="TestName" select="FullName" />
    <Test>
      <Name><xsl:value-of select="$TestName" /></Name>
      <xsl:for-each select="$BuildStamps/Testing">
        <xsl:variable name="Test"
                      select="Tests/Test[FullName = $TestName]" />
        <Result>
          <xsl:copy-of select="SiteName" />
          <Status>
            <xsl:choose>
              <xsl:when test="$Test">
                <xsl:value-of select="$Test" />
              </xsl:when>
              <xsl:otherwise>NA</xsl:otherwise>
            </xsl:choose>
          </Status>
        </Result>
      </xsl:for-each>
    </Test>
  </xsl:for-each>

If you have *lots* of tests within each site, then you could consider
having a key to enable you to retrieve the Test element with a
particular name for a particular site. The key would look like:

<xsl:key name="TestSites" match="Test"
         use="concat(../../SiteName, '::', FullName)" />

and in the xsl:for-each from above, you would set the $Test variable
with the following path instead:

  key('TestSites', concat(SiteName, '::', $TestName))

I hope that helps,

Jeni

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


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


Current Thread