Gabe Rainbow
Gabe Rainbow

Reputation: 3748

xpath xsl concat

given the following

<ZIP0>10015</ZIP0>
<ZIP1>10016</ZIP1>
...
<ZIP99>10016</ZIP99>

im using xpath concat() in order to combine the element name and integer:

<ZIP><xsl:value-of select="concat('ZIP','0')"/></ZIP>

concat returns the literal string...

<ZIP>ZIP0</ZIP>

of course, what is intented is,

<ZIP>10015</ZIP>

how to evaluate the string expression returned from concat.

and this also offers the same result:

<xsl:variable name="tmp" select="concat('ZIP','0')"/>
<ZIP><xsl:value-of select="$tmp"/></ZIP>

in fact, its evaluated like,

<xsl:value-of select="'ZIP0'"/>

opposed to

<xsl:value-of select="ZIP0"/>

cheers

Upvotes: 0

Views: 2899

Answers (1)

Guido Simone
Guido Simone

Reputation: 7952

Short answer:

<ZIP><xsl:value-of select="*[name() = concat('ZIP','1')]"/></ZIP>

Long answer - in an expression like the following:

<xsl:value-of select="ZIP1"/>

ZIP1 is actually shorthand for child::ZIP1 which means (roughly) look for a child element with a name matching ZIP1. The text ZIP1 is called a name test. Unfortunately there is no way to build a name test dynamically from strings. You have to either specify the name exactly or use a wildcard *.

Since we don't know the exact name, we have no choice but to use the wildcard * followed by a predicate expression which filters out the nodes we are not interested in. The predicate will be invoked on every node in our list. The name() method will return the tag name of the node being tested, so all we have to do is ensure that the name equals the string that we want.

For reference see http://www.w3.org/TR/xpath

Upvotes: 4

Related Questions