How do I check if XML value is nil in XSLT
Asked Answered
W

5

6

In an XML document I have some address data..

<zip>08001</zip>
<zipPlus xsi:nil="true" />

and

<zip>08002</zip>
<zipPlus>4512</zipPlus>

On only want to bother displaying the zip plus value if there is a value to use. (for the purposes of this example, I don't care if its a correct zip plus format or not)

Trying to use the following snippet in an XSLT never seems to work right, and I think it has to do with how I am checking for the xsl:nil value

<EmployerZipCode>
      <xsl:value-of select="zip"/>
      <xsl:if test="zipPlus != @xsl:nil">
        <xsl:value-of select="'-'"/>
        <xsl:value-of select="zipPlus"/>
      </xsl:if>
      <xsl:value-of select="$sepChar"/> <!--this is a comma -->
</EmployerZipCode>

The results I get are always

08001,
08002,

not

08001,
08002-4512,

What is the proper way to check for nil-led elements in XSLT? Are there any other ways to get around this problem and get the result I want?

Windproof answered 9/6, 2011 at 16:20 Comment(0)
W
3

After some more testing, none of answers given that involve checking the nil attribute work reliably.

I had to resort to using string-length() to get the result I needed.

<EmployerZipCode>
  <xsl:value-of select="zip"/>
  <xsl:if test="string-length(zipPlus) &gt; 0">
    <xsl:value-of select="'-'"/>
    <xsl:value-of select="zipPlus"/>
  </xsl:if>
  <xsl:value-of select="$sepChar"/>
</EmployerZipCode>
Windproof answered 10/6, 2011 at 20:4 Comment(1)
See my answer. I'm testing just with not(zipPlus/@xsi:nil) assuming that if the attribute is missing you want the zipplus. However @Jim-Garrison works either (even if in my test you need to replace prefix xsl with xsi).Hereford
S
6
<xsl:if test="not(zipPlus/@xsi:nil='true')">
Surface answered 9/6, 2011 at 16:40 Comment(1)
If @xsl:nil is present only when the value is "true", then use not(zipPlus/@xsl:nil) which tests for the existence of the attribute.Surface
S
5

In XSLT 2.0, for reasons I have never fully understood, there is a custom function

test="not(nilled(zipPlus))"
Samadhi answered 9/6, 2011 at 20:4 Comment(2)
the xslt debugging in visual studio does not know about the nilled() function.Windproof
D'oh. just realized that VS2010 only supports XSLT 1.0. That's super lame. Thanks anyway @Michael KayWindproof
W
3

After some more testing, none of answers given that involve checking the nil attribute work reliably.

I had to resort to using string-length() to get the result I needed.

<EmployerZipCode>
  <xsl:value-of select="zip"/>
  <xsl:if test="string-length(zipPlus) &gt; 0">
    <xsl:value-of select="'-'"/>
    <xsl:value-of select="zipPlus"/>
  </xsl:if>
  <xsl:value-of select="$sepChar"/>
</EmployerZipCode>
Windproof answered 10/6, 2011 at 20:4 Comment(1)
See my answer. I'm testing just with not(zipPlus/@xsi:nil) assuming that if the attribute is missing you want the zipplus. However @Jim-Garrison works either (even if in my test you need to replace prefix xsl with xsi).Hereford
H
1

It's very strange that you didn't get it to work. Perhaps it might be you are missing namespace declaration or the prefix change xsi to xsl is an unseen typo in your transform. Check better. Here my test:

XSLT 1.0 with Saxon 6.5

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="test">
    <xsl:output method="text" indent="yes"/>

    <xsl:template match="EmployerZipCode">
        <EmployerZipCode>
            <xsl:value-of select="zip"/>
            <xsl:if test="not(zipPlus/@xsi:nil)">
                <xsl:value-of select="'-'"/>
                <xsl:value-of select="zipPlus"/>
            </xsl:if>
            <xsl:value-of select="','"/> <!--this is a comma -->
        </EmployerZipCode>
    </xsl:template>
</xsl:stylesheet>

Given the input:

<?xml version="1.0" encoding="utf-8"?>
<test xmlns:xsi="test">
    <EmployerZipCode>
        <zip>08001</zip>
        <zipPlus xsi:nil="true" />
    </EmployerZipCode>
    <EmployerZipCode>
        <zip>08002</zip>
        <zipPlus>4512</zipPlus>
    </EmployerZipCode>
</test>

Produces:

08001,
08002-4512,
Hereford answered 10/6, 2011 at 22:12 Comment(0)
L
1

It works for me

Source XML :

            <zipPlus xsi:nil="true"/>
                      or
            <zipPlus>123456</zipPlus>

XSLT :

            <xsl:if test="not(zipPlus/@xsl:nil='true')">
                <xsl:value-of select="zipPlus"/>
            </xsl:if>

Result XML

            <zipPlus/>
            or
            <zipPlus>123456</zipPlus>
Lalonde answered 18/10, 2011 at 9:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.