2

I am fairly new to xml and I'm having a weird problem with templates. For empty data nodes, instead of displaying a blank space where the data should be, I want to display a message like 'None Found' or 'No Data' on an html page. I have done both an xsl:choose statement and 2 xsl:if statements with no success. I already know this particular node is empty, I just want to show a message instead of a blank space. The Otherwise or False statements just don't seem to run at all. Please help!! What am I doing wrong here?

The XML Code

<?xml version="1.0" encoding="UTF-8"?>
<Root>
<findings>
    <ssns/>
    <dobs>
     <dob>
         <data>082967</data>
     </dob>   
    </dobs> 
    <dobs>
        <dob>
         <data>020568</data>
        </dob>
    </dobs>
 
    <names>
        <name>
        <full>Homer J Simpson</full>
        <first>Homer</first>
        <last>Simpson</last>
        <middle>J</middle>
        </name>
    </names>
    <names>
        <name>
        <full>Marge H Simpson</full>
        <first>Marge</first>
        <last>Simpson</last>
        <middle>H</middle>
        </name>
    </names>
</findings>
</Root>

The XSL Code

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="/">
      <hmtl>
        <head>
          <title>Person Results</title>
        </head>
        
        <div style="font-weight:bold">Alias(es):</div>
        <xsl:apply-templates select="Root/findings/names"/>
        
        <div style="font-weight:bold">SSNs:</div>
        <xsl:apply-templates select="Root/findings/ssns"/>
        
        <div style="font-weight:bold">DOBs:</div>
        <xsl:apply-templates select="Root/findings/dobs"/>
      </hmtl>
    </xsl:template>

    
    <xsl:template match="Root/findings/names">
      <p>
      <xsl:variable name="nmesHasData" select="boolean(normalize-space(name))"/>
        <xsl:for-each select="name">
        <xsl:choose>
          <xsl:when test="$nmesHasData">
            <ul> <xsl:apply-templates select="full"/> </ul>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>None found</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
        </xsl:for-each>
      </p>
    </xsl:template>
    
    <xsl:template match="Root/findings/ssns">
      <p>
        <xsl:variable name="ssnHasData" select="boolean(normalize-space(ssns))"/>
        <xsl:for-each select="ssn">
        <xsl:choose>
          <xsl:when test="$ssnHasData">
           <ul><xsl:apply-templates select="data"/></ul>
         </xsl:when>
          <xsl:otherwise>
            <xsl:text>None found</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
        </xsl:for-each>
      </p>
  
    </xsl:template>
    
    <xsl:template match="Root/findings/dobs">
      <p>
        <xsl:variable name="dobHasData" select="boolean(normalize-space(dob))"/>
        <xsl:for-each select="dob">
        <xsl:choose>
          <xsl:when test="$dobHasData">
           <ul><xsl:apply-templates select="data"/></ul>
         </xsl:when>
          <xsl:otherwise>
            <xsl:text>None found</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
        </xsl:for-each>
      </p>
  
    </xsl:template>
    
</xsl:transform>

The HTML Result

<!DOCTYPE html
  PUBLIC "XSLT-compat">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Person Results</title>
   </head>
   <div style="font-weight:bold">Alias(es):</div>
   <p>
      <ul>Homer J Simpson</ul>
   </p>
   <p>
      <ul>Marge H Simpson</ul>
   </p>
   <div style="font-weight:bold">SSNs:</div>
   <p></p>
   <div style="font-weight:bold">DOBs:</div>
   <p>
      <ul>082967</ul>
   </p>
   <p>
      <ul>020568</ul>
   </p>
</html>
  • Please edit your question and add 2 examples of XML input: one that qualifies as "empty" and one that does not - see: [mcve]. – michael.hor257k Apr 22 '22 at 05:16
  • Change $dobHasData = 'true' to $dobHasData = true() – Siebe Jongebloed Apr 22 '22 at 06:44
  • @SiebeJongebloed What difference would that make? – michael.hor257k Apr 22 '22 at 08:38
  • Which version of XSLT do you use? Can a `dobs` element have several `dob` child elements? Do you want to process/check each of them separately? – Martin Honnen Apr 22 '22 at 10:00
  • @michael.hor257k, I have modified my submission to show a fuller picture of my code. I guess I'm referring to the template correctly, right? I have a feeling that my issue has to do with my trying to display text outside of the HTML block...? – Gerald Hendrix Apr 22 '22 at 17:43
  • @SiebeJongebloed, thanks for the suggestion, but that did not make a difference, I'm still getting blank results and no text message. – Gerald Hendrix Apr 22 '22 at 17:44
  • I don’t see any dobs element in your xml, although you are using it in the match where you are testing the empty dob? – Siebe Jongebloed Apr 22 '22 at 19:02
  • @SiebeJongebloed, sorry I left off the 's' from DOB in my code. DOB is short for Date of Birth, which in this case, the node is empty. I'm just trying to display a text message when there is nothing in the node. – Gerald Hendrix Apr 22 '22 at 19:18
  • Be more precise in your sample xsl and source xsl. The xml was not well-formed and there was a mismatch between the xml-element Root and xsl-xpath root. Now we have to guess what you want. I hope my guessing was correct :-) – Siebe Jongebloed Apr 22 '22 at 20:15
  • @SiebeJongebloed, I have modified my sample xml and source xsl to be more clear. The main problem I'm having is that I just want to display "nothing found" for an empty node. In my modified code above, the empty node is now "". However the 'None found' text never displays even though it has no data. What am I doing wrong here? – Gerald Hendrix Apr 23 '22 at 10:53

1 Answers1

1

Change the template match="Root/findings/dobs" to this:

  <xsl:template match="Root/findings/dobs">
    <p>
      <xsl:for-each select="dob">
        <xsl:variable name="dobHasData" select="boolean(normalize-space(.))"/>
        <xsl:choose>
          <xsl:when test="$dobHasData">
            <ul><xsl:apply-templates select="data"/></ul>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>None found</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </p>
    
  </xsl:template>

Or even more template matching like:

  <xsl:template match="Root/findings/dobs">
    <p>
      <xsl:apply-templates select="dob"/>
    </p>
  </xsl:template>
  
  <xsl:template match="dob">
      <xsl:variable name="dobHasData" select="boolean(normalize-space(.))"/>
      <xsl:choose>
        <xsl:when test="$dobHasData">
          <ul><xsl:apply-templates select="data"/></ul>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>None found</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
  </xsl:template>

And this last template could also be splitted in two short ones:

  <xsl:template match="dob[normalize-space(.)]">
    <ul><xsl:apply-templates select="data"/></ul>
  </xsl:template>

  <xsl:template match="dob[not(normalize-space(.))]">
    <xsl:text>None found</xsl:text>
  </xsl:template>
  
Siebe Jongebloed
  • 3,906
  • 2
  • 14
  • 19