0
votes

I have a table that is populated from a SQL database. Most of the data entered will have an ABN which I can use to look up email and name. Some data doesn't have an ABN, and only has a UID. I don't want to have to display the UID in the table since its unnecessary 98% of the time, so I want to use an xsl:when to change the name field to the UID if there isn't a name.

Here is an example of the 2 cases in XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <CourseData>
      <row batchid="0" courseid="10101" createdon="04/03/2012 01:08PM" datecompleted="1:08 PM" datecompletedDateValue="1333483680000" lastupdatebyabn="999999" lastupdatebyuid="tsmith" lastupdateon="04/03/2012 01:08PM" num="2" respondentabn="999999" respondentemail="[email protected]" respondentid="1" respondentname="Thomas Smith" respondentuid="tsmith"/>       
      <row batchid="0" courseid="10101" createdon="04/03/2012 01:08PM" datecompleted="1:08 PM" datecompletedDateValue="1333483697000" lastupdatebyabn="" lastupdatebyuid="jsmith" lastupdateon="04/03/2012 01:08PM" num="3" respondentabn="" respondentemail="" respondentid="2" respondentname=" " respondentuid="jsmith"/>
    </CourseData>

Here is the XSL I'm using, which obviously isn't working.

    <xsl:choose>
      <xsl:when test="row[@respondentabn='']">
        <label datafield="@respondentuid"></label>
      </xsl:when>
      <xsl:otherwise>
        <label datafield="@respondentname"></label>
      </xsl:otherwise></xsl:choose></td>

How can I fix this?

Edit: So after talking to my boss, he said for one I'd need an loop in there for this to work right, but that I really shouldn't be doing this in the .xsl anyways. I modified my sql that is serving up the data to make that change for me, which in retrospect, I probably should have thought of in the first place.

2
Please show some expected output and more of the XSL showing the context in which this <xsl:choose> is invoked. The test row[@respondentabn=''] is looking for the existence of a row with respondentabn equal to a zero length string. If applied with CourseData as the context node it is true because there exists one such row.Jim Garrison

2 Answers

0
votes

You don't give much indication of the stylesheet so it's hard to be sure but I'd guess you have something like

<xsl:for-each select="row">
<xsl:choose>
      <xsl:when test="row[@respondentabn='']">
        <label datafield="@respondentuid"></label>
      </xsl:when>
      <xsl:otherwise>
        <label datafield="@respondentname"></label>
      </xsl:otherwise>
</xsl:choose>
</xsl:for-each>

or in any event if the current node is such that row[@respondentabn=''] does anything useful it must be the parent of row in which case <label datafield="@respondentuid"> would select attributes of the parent (even if the AVT syntax was corrected).

So I would guess:

<xsl:for-each select="row">
<xsl:choose>
      <xsl:when test="string(@respondentabn)">
        <label datafield="{@respondentuid}"></label>
      </xsl:when>
      <xsl:otherwise>
        <label datafield="{@respondentname}"></label>
      </xsl:otherwise>
</xsl:choose>
</xsl:for-each>

Or, more tersely

<xsl:for-each select="row">
   <label datafield="{@respondentuid[string(.)]|
                      @respondentname[not(string(../@respondentuid))]}"/>
 </xsl:for-each>
0
votes

With XSLT, you cannot check for the presence of an empty string in the strict sense. the easiest way to do this then is to evaluate the inverse:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="/">
        <doc>   
           <xsl:apply-templates select="CourseData/row"/>   
        </doc>
    </xsl:template>

    <xsl:template match="CourseData/row"> 
        <xsl:choose>
            <xsl:when test="@respondentabn!=''"> 
                <xsl:element name="label">
                    <xsl:attribute name="datafield">
                       <xsl:value-of select="@respondentname"></xsl:value-of>   
                    </xsl:attribute>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:element name="label">
                    <xsl:attribute name="datafield">
                        <xsl:value-of select="@respondentuid"></xsl:value-of>
                    </xsl:attribute>
                </xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template> 

</xsl:stylesheet>

produces:

<doc><label datafield="Thomas Smith" /><label datafield="jsmith" /></doc>

Another approach would be to assign the value of the respondentabn attribute to a variable, you could then evaluate the when clause against the variable instead:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="/">
        <doc>   
           <xsl:apply-templates select="CourseData/row"/>   
        </doc>
    </xsl:template>

    <xsl:template match="CourseData/row"> 
        <xsl:variable name="respondentabn">
           <xsl:value-of select="@respondentabn"/>
        </xsl:variable>

        <xsl:choose>
          <xsl:when test="$respondentabn=''">
            <xsl:element name="label">
               <xsl:attribute name="datafield">
                  <xsl:value-of select="@respondentuid"/>
               </xsl:attribute>
            </xsl:element>
          </xsl:when>
          <xsl:otherwise>
            <xsl:element name="label">
               <xsl:attribute name="datafield">
                  <xsl:value-of select="@respondentname"/>
               </xsl:attribute>
            </xsl:element>
          </xsl:otherwise>
        </xsl:choose>

    </xsl:template> 

</xsl:stylesheet>

produces:

<doc><label datafield="Thomas Smith" /><label datafield="jsmith" /></doc>

Both approaches will do what you need, its just a matter of which one is more understandable for you.