No Way
No Way

Reputation: 193

XSLT 1.0: how to get print of first non-empty value of two (see inside)

I want to get first non-empty value of two and put it to "value" attribute of a text input. So, I do:

<input type="text">
  <xsl:attribute name="value">
    <xsl:choose>
      <xsl:when test="some/@attr != ''">
        <xsl:value-of select="some/@attr" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="some/another/@attr" /> <!-- always non-empty, so get it -->
      </xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>
</input>

Question is: is there a way to make it with less lines of code?.. Maybe, like that: <input type="text" value="some/@attr or some/another/@attr" /> or something?.. Like in, say, Perl: my $val = 0 || 5;

Thanks in advance for your help

UPD XSLT 1.0

Upvotes: 3

Views: 1565

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

Even the union can be avoided:

<input type="text" 
       value="{some/@attr[string(.)]}{some[not(string(@attr))]/another/@attr}">
</input>

Here we also avoid the precedence dependence of the two attributes that is common to all other given answers -- we don't suppose that the first attribute precedes the second attribute in document order.

We could write this equivalent code, reversing the order of the two AVTs:

<input type="text" 
       value="{some[not(string(@attr))]/another/@attr}{some/@attr[string(.)]}">
</input>

Upvotes: 3

hr_117
hr_117

Reputation: 9627

The relay magic is already in the answer form @Martin Honnen. As enhancement,to make it even a little shorter you can use "Attribute Value Templates"

<input type="text" value="{some/@attr[. != ''] | some/another/@attr}">
</input>

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167571

If you use

<xsl:attribute name="value">
  <xsl:value-of select="some/@attr[. != ''] | some/another/@attr"/>
</xsl:attribute>

then with XSLT 1.0 value-of semantics the string value of the first node selected by some/@attr[. != ''] | some/another/@attr is output. Thus if some/@attr[. != ''] selects a node it should be output, otherwise some/another/@attr (as I think some/@attr is considered preceding some/child-element/@attr in document order).

Upvotes: 6

Related Questions