devW
devW

Reputation: 23

xsl get array of elements

Hi I need get array of elements (before "-" if exist) by xsl.

xml is

<Cars>
<Car Trunck="511"/>
<Car Trunck="483-20"/>
<Car Trunck="745"/>
</Cars>

xsl is

<xsl:variable name="testarr">
<xsl:for-each select="//Cars//Car/@Trunck">
<xsl:value-of select="number(substring(.,1,3))" />
                </xsl:for-each>
                        </xsl:variable>

(i suppose that all numbers is three-digit number, if someone knows a solution for all conditions will be glad to hear the proposal) if i do this i get all numbers in one line: 511483745 and i need get them in array because i also need get the max value

thanks

Upvotes: 2

Views: 4174

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

While you have two good answers (especially that by @Alejandro), here's one from me that I think is even better:

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:param name="pTopNums" select="2"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="*">
   <xsl:sort data-type="number" order="descending"
    select="substring-before(concat(@Trunck,'-'),'-')"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="Car">
  <xsl:if test="not(position() > $pTopNums)">
   <xsl:value-of select=
   "substring-before(concat(@Trunck,'-'),'-')"/>
   <xsl:text>&#xA;</xsl:text>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

when applied on this XML document (the originally provided one, slightly changed to be more challenging):

<Cars>
    <Car Trunck="483-20"/>
    <Car Trunck="311"/>
    <Car Trunck="745"/>
</Cars>

produces the wanted, correct result (the top two numbers that are derived from @Trunck as specified in the question):

745
483

Upvotes: 0

user357812
user357812

Reputation:

Hi I need get array of elements (before "-" if exist) [...] i need get them in array because i also need get the max value

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:for-each select="/Cars/Car/@Trunck">
            <xsl:sort select="concat(substring-before(.,'-'),
                                     substring(., 1 div not(contains(.,'-'))))"
                  data-type="number" order="descending"/>
            <xsl:if test="position()=1">
                <xsl:value-of
                     select="concat(substring-before(.,'-'),
                                    substring(.,1 div not(contains(.,'-'))))"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Output:

745

XPath 2.0 one line:

max(/Cars/Car/@Trunck/number(replace(.,'-.*','')))

Upvotes: 2

peter.murray.rust
peter.murray.rust

Reputation: 38033

You could use the substring-before and substring-after functions: See the excellent ZVON tutorial http://zvon.org/xxl/XSLTreference/Output/function_substring-after.html

In your example you are only extracting the values (which are strings) which get concatenated. Perhaps you need to wrap the result in your own element

<xsl:for-each select="//Cars//Car/@Trunck">
  <truck>
    <xsl:value-of select="number(substring(.,1,3))" />
  </truck>
</xsl:for-each>

Upvotes: 1

Related Questions