[xquery-talk] How to handle empty sequence?

Ed O'Neill tenacious61 at sbcglobal.net
Mon Jan 17 23:51:54 PST 2005


Hello All,

  I'm new to xquery, and the list.  I have been using xml to track a set
software applications and their deployment into several environments. The
form of a release is that it has general descriptive information, and then
environment (env) elements, for each of the environments the application has
been deployed to (note that it may not be deployed to all environments).

<releases>
  <release>
    <name>CATALOG</name>
    <version>9.00.00</version>
    <env>
      <name>qa</name>
      <actual_deploy_dt>2004-02-19</actual_deploy_dt>
    </env>
    <env>
      <name>uat</name>
      <actual_deploy_dt>2004-02-25</actual_deploy_dt>
    </env>
    <env>
      <name>trn</name>
      <actual_deploy_dt>2004-03-05</actual_deploy_dt>
    </env>
    <env>
      <name>prd</name>
      <actual_deploy_dt>2004-03-05</actual_deploy_dt>
    </env>
  </release>
  etc
</releases>

When a new version of this application is released, I'll add a new release
element for that version.

My objective is to be able to generate a table in html that displays each of
my applications, and the current version of the application in each
environment (identified by having the most recent deployment date in the
env).

This is my first attempt with Xquery, and I'm using the qizxopen
implementation.

Here's the relevant portion of my query.

<TABLE border="1">
<TR  CLASS="table_header">
    <TH>Appl.</TH>
    <TH>QC</TH>
    <TH>UAT</TH>
    <TH>TRN</TH>
    <TH>PRD</TH>
</TR>

  {
    let $release := ( document ("release_schedule.xml")//release)
    let $relnames := ("MSA","PPA","AMA","ISA","ABE","RMA","CATALOG")
    for $relname in $relnames
    let $rowClass   :=    if (index-of($relnames,$relname) mod 2 = 0) then
"evenRow"
            else "oddRow"
      return
        <tr CLASS="{$rowClass}">
               <td><CENTER>{$relname}</CENTER></td>
            {    for $env in ("qa","uat","trn","prd")
              return
            let $sorted_releases := for $release2 in $release
                where $release2/name = $relname
                and $release2/env/name = $env
                order by 
substring(string($release2/env/actual_deploy_dt/node()),1,4)
                  descending
               
 ,substring(string($release2/env/actual_deploy_dt/node()),6,2) descending
               
 ,substring(string($release2/env/actual_deploy_dt/node()),9,2) descending
                return
                $release2

            for $release3 in $sorted_releases[position()<2]
            let $version := ($release3/version)
            return
              <td>
              <CENTER>
              {
               if (string-length(string($version/node())) = 0) then "NA"
               else $version/node()
               }
            </CENTER>
            </td>

         }
        </tr>
  }
</TABLE>

This query works fine if all applications have a version in each
environment. The problem is when I have an application that does not have
any versions released to a particular env. .When this occurs, the
$sorted_releases sequence will be empty, so I never get to "for $release3"
return to generate the necessary table element (which would be blank).

I tried to handle this with by testing the $release2 returned in the
$sorted_releases using an if statement such as "if ($release2) then
$release2 else 'NA' " but then the "let $version" assignment noted that the
"NA" was a string, not a node.

Thanks for any insight.

Ed




More information about the talk mailing list