Mohamed Ahmed
Mohamed Ahmed

Reputation: 27

XSL template for matching empty text

I'm still newbie in xsl, I basically have XML file containing a set of tags like this

<Property name="errors"><Property> 

and Need to Change them into

<Property name="errors">empty<Property>

So I created a template for text() and check inside if the text of this property is empty '' then I Change it into 'empty'

infact it works like a charm if i want to Change any string to other like 'none' to 'empty' but doesn't work on null or empty strings

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Property/text()">
  <xsl:choose>
  <xsl:when test=". = 'none'">
    <xsl:choose>
      <xsl:when test="../@name = 'errors'">
        <xsl:value-of select="'empty'"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="." />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:when>
  <xsl:when test=". = ''">
      <xsl:choose>
        <xsl:when test="../@name = 'errors'">
          <xsl:value-of select="'empty'"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="." />
        </xsl:otherwise>
      </xsl:choose>
   </xsl:when>
   <xsl:otherwise>
     <xsl:value-of select="." />
   </xsl:otherwise>
 </xsl:choose>
</xsl:template>

Upvotes: 1

Views: 3692

Answers (2)

Michael Kay
Michael Kay

Reputation: 163625

Match the empty elements, not the (non-existent) text nodes:

<xsl:template match="Property[. = '']">
  <Property>empty</Property>
</xsl:template>

Upvotes: 2

Philipp
Philipp

Reputation: 4749

When an XML Element is empty <element></element> you can consider it as <element/>. So there is no text() node inside the element. So your template does not match the empty/null elements.

Make your template to match the element. Then inside make the choose on the existence of the text() content with the test not(text()). I also put the conditions with and and or together.

<xsl:template match="Property">
    <xsl:copy>
        <xsl:choose>
            <xsl:when test="@name = 'errors' and (not(text()) or text()='none')">
                <xsl:value-of select="'empty'"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="text()"/>
            </xsl:otherwise>
        </xsl:choose>       
    </xsl:copy>
</xsl:template>

Upvotes: 2

Related Questions