Display values

R

Ravi

My xml looks like

<abc>
23 45 67 2 123
</abc>

I wish to display these values comma separated

23; 45; 67; 2; 123

However if I use <xsl:value-of select="abc"> I get the entire list of
values i.e. all 5 values. How can I obtain each component of the value?
I cannot use for-each to select the value of each child as abc has no
children in this case. Or should I modify the xml itself to include the
comma?

TIA.
 
M

Maarten Wiltink

Ravi said:
My xml looks like

<abc>
23 45 67 2 123
</abc>

I wish to display these values comma separated

23; 45; 67; 2; 123

However if I use <xsl:value-of select="abc"> I get the entire list of
values i.e. all 5 values. How can I obtain each component of the value?
I cannot use for-each to select the value of each child as abc has no
children in this case. Or should I modify the xml itself to include the
comma?

If you can modify the XML, you might start generating it as
<abc>
<nr>23</nr>
<nr>56</nr>
<nr>67</nr>
<nr>2</nr>
<nr>123</nr>
</abc>
which would make transforming it into a separated list a lot easier.

With your current XML, it would be possible using a recursive template
and the substring-before function.

The root of the problem is that five distinct entities have been rolled
into a single text node.

Groetjes,
Maarten Wiltink
 
J

Johannes Koch

Ravi said:
My xml looks like

<abc>
23 45 67 2 123
</abc>

I wish to display these values comma separated

23; 45; 67; 2; 123

<xsl:value-of select="translate(abc,' ',';')"/>

will result in

23;45;67;2;123
 
P

Patrick TJ McPhee

% <abc>
% 23 45 67 2 123
% </abc>
%
% I wish to display these values comma separated
%
% 23; 45; 67; 2; 123

Those are semi-colons, not commas. To do this in XSLT, you need to
create a recursive template. The approach is to create a template which
takes two arguments, s and t. If the s is zero-length, the template
emits t. Otherwise, it builds new arguments, moving the first word of s
to the end of t, and calls itself.

<xsl:template match="abc">
<xsl:call-template name="semi-colonify">
<xsl:with-param name="s" select="string(.)"/>
</xsl:call-template>
</xsl:template>


<xsl:template name="semi-colonify">
<xsl:param name="s"/>
<xsl:param name="t"/>

<xsl:choose>
<!-- s is not zero-length, so split it -->
<xsl:when test="$s">
<xsl:call-template name="semi-colonify">
<xsl:with-param name="t">
<!-- need to fiddle if there's already a t -->
<xsl:if test="$t">
<xsl:value-of select="$t"/>
<xsl:text>; </xsl:text>
</xsl:if>
<xsl:variable name="sbs" select="substring-before($s, ' ')"/>
<xsl:choose>
<xsl:when test="$sbs">
<xsl:value-of select="$sbs"/>
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select="$s"/>
</xsl:eek:therwise>
</xsl:choose>
</xsl:with-param>

<xsl:with-param name="s" select="substring-after($s, ' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select="$t"/>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

XSLT can handle most string processing problems, but you may find
it's easier to use another language. You have to balance portability
requirements against your ability to be productive. For instance,
this could be done with Rexx:

<rexx:function name='my:semi-colonify' all-strings='yes'>
return changestr(' ', arg(1), '; ')
</rexx:function>

<xsl:template match="abc">
<xsl:value-of select='my:semi-colonify(.)'/>
</xsl:template>

Something similar can likely be done equally portably using python or
a bit more portably using ecma script.
 

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

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top