XSLT: how do I implement a VB-like IIF in XPath for setting attribute values?

V

Vince C.

Hi, all.

I'd like to know if there's a way to simplify writing attribute values in XSLT.
The case is the following:

<xsl:template ...>
<div id="{ if (@id) @id else generate-id() }">Div Text</div>
</xsl:template>

If context node has an @id then I want that id for output. Otherwise I want to
generate an id if there is none. I know the "long" method which is:

<xsl:attribute name="id">
<xsl:choose>
<xsl:when test="@id"><xsl:value-of select="@id"/></xsl:when>
<xsl:eek:therwise><xsl:value-of select="generate-id()"/></xsl:eek:therwise>
</xsl:choose>
</xsl:attribute>

But it's too long to me. Is there a shortcut? Note as I'm using MSXML4 I can use
MS XSL extensions too.

Thanks for any hint/suggestion,
Vince C.
 
D

Dimitre Novatchev

Try:

<div id="{ concat(@id, generate-id(self::*[not(@id and
string(@id))]))}">Div Text</div>

This transformation:

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

<xsl:template match="div">
<div id="{ concat(@id, generate-id(self::*[not(@id and
string(@id))]))}">Div Text</div>
</xsl:template>
</xsl:stylesheet>

when applied on this source.xml:

<t>
<div id="1">xxx</div>
<div id="">yyy</div>
<div>zzz</div>
</t>

produces the wanted result:

<?xml version="1.0" encoding="UTF-16"?>
<div id="1">Div Text</div>
<div id="IDAJA2S">Div Text</div>
<div id="IDANA2S">Div Text</div>


Hope this helped.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
 
V

Vince C.

Thanks, Dean.

Dean Tiegs said:
You could split it into two templates:

That's exactly what I wanted to work around since I have somewhat duplicated
templates.

Vince C.
 
V

Vince C.

Dimitre Novatchev said:
Try:

<div id="{ concat(@id, generate-id(self::*[not(@id and
string(@id))]))}">Div Text</div>

This transformation:

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

<xsl:template match="div">
<div id="{ concat(@id, generate-id(self::*[not(@id and
string(@id))]))}">Div Text</div>
</xsl:template>
</xsl:stylesheet>

when applied on this source.xml:

<t>
<div id="1">xxx</div>
<div id="">yyy</div>
<div>zzz</div>
</t>

produces the wanted result:

<?xml version="1.0" encoding="UTF-16"?>
<div id="1">Div Text</div>
<div id="IDAJA2S">Div Text</div>
<div id="IDANA2S">Div Text</div>


Hope this helped.

Great! That's exactly what I wanted. If none of my IDs are empty, i.e. <div
id="">, I presume I can safely omit [and string(@id)] in the filter?

Note I didn't know there had a way to have generate-id() return an empty
string.

Vince C.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top