Jessica_the_owl
Jessica_the_owl

Reputation: 71

How can you apply concat(...) in a value-of directive in case of multiple nodes?

I am outputting the name node of each property node in a ; delimited string as following:

<xsl:value-of select="properties/property/name" separator=";" />

I want to alter this such that each element is prefixed with _. An example output should be:

_alpha;_beta;_gamma

I tried the following:

<xsl:value-of select="concat('_', properties/property/name)" separator=";" />

I want to use this to create an output node containing that string:

<my_node>
    <xsl:value-of select="concat('_', properties/property/name)" separator=";" />
</my_node>

This gives an error when there are multiple properties:

XPTY0004: A sequence of more than one item is not allowed
          as the second argument of fn:concat() (<name>, <name>)

Is there a way to get this working in XSLT 2.0/3.0?

I could resort to the XSLT 1.0 for-each solution as given in https://stackoverflow.com/a/57856287/12042211 (in which we are manually adding the separator), but I am wondering if something elegant in XSLT 2.0/3.0 is possible.

Upvotes: 1

Views: 127

Answers (2)

Michael Kay
Michael Kay

Reputation: 163458

In XSLT 3.0 I would tend to write this as

<xsl:value-of select="properties/property ! ('_' || name)" separator=";" />

and perhaps use string-join() instead of xsl:value-of. You haven't shown the context, but try to use xsl:value-of only when you really want a text node, not when you just want a string.

Upvotes: 1

Tim C
Tim C

Reputation: 70638

The answer is yes. XSLT 2.0 allows you to write expressions like this...

<xsl:value-of select="properties/property/concat('_', name)" separator=";" />

So, for each property it selects the concatenation of "_" with the name element.

Such syntax is not valid in XSLT 1.0 though.

Upvotes: 3

Related Questions