Re: [xsl] Iterating over values in a table of data

Subject: Re: [xsl] Iterating over values in a table of data
From: "Neil Crofts" <neil.crofts@xxxxxxxxx>
Date: Wed, 7 Jun 2006 11:13:49 +0100
Thanks for everyones thoughts/solutions.

I didn't say originally that the XML was generated by aggregating data
obtained from a third-party source with another XML-based language
that references that data.

If you have a view on a better way to represent the combination of
this data to make solving the original problem more straightforward
then I would appreciate your comments. Thanks.



On 07/06/06, andrew welch <andrew.j.welch@xxxxxxxxx> wrote:
On 6/7/06, Neil Crofts <neil.crofts@xxxxxxxxx> wrote:
> I'm trying to transform some XML which is supposed to act as an
> iterator/repeat statement without much success at the moment. I was
> wondering if anyone had some advice about the best way to approach
> this sort of problem. For example, my source XML looks a bit like the
> following:
>
> <input>
>     <!-- This is a table of lookup values. -->
>     <data>
>         <item>
>             <value>one</value>
>         </item>
>         <item>
>             <value>two</value>
>         </item>
>         <item>
>             <value>three</value>
>         </item>
>     </data>
>     <!-- This node needs to be repeatedly transformed for each input
> data item -->
>     <repeat>
>             Item <value-of name="value"/> is in position <position-of
> name="value"/>
>     </repeat>
> </input>
>
> The desired output is of the following format:
>
> <output>
> <item>Item one is in position 1</item>
>           <item>Item two is in position 2</item>
>           <item>Item three is in position 3</item>
> </output>
>
> The intention is that when a <repeat> node is transformed it will look
> up the value of the next item in the data table and output its value
> and also its position in the data table. This will need to be repeated
> for each data item.
>
> I don't have a restriction on me regarding the version of XSLT I can
> use, so an XSLT 2.0 specific would be ok, although I would prefer a
> solution that does not use any processor specific extensions.
>
> Has anyone got any advice on or solutions for this class of problem? Thanks.

You win todays prize for nasty XML - its looks like the XML designed
with processing in mind, rather than just describing the data, and
this has backfired because its reasonably involved to achieve what you
are after.

Here is an XSLT 1.0 solution:

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

<xsl:template match="/">
        <output>
                <xsl:apply-templates select="input/repeat"/>
        </output>
</xsl:template>

<xsl:template match="repeat">
        <xsl:variable name="this" select="."/>
        <xsl:for-each select="/input/data/item">
                <item>
                        <xsl:variable name="value" select="value"/>
                        <xsl:variable name="pos" select="position()"/>
                        <xsl:apply-templates select="$this/node()">
                                <xsl:with-param name="value" select="$value"/>
                                <xsl:with-param name="pos" select="$pos"/>
                        </xsl:apply-templates>
                </item>
        </xsl:for-each>
</xsl:template>

<xsl:template match="value-of">
        <xsl:param name="value"/>
        <xsl:value-of select="$value"/>
</xsl:template>

<xsl:template match="position-of">
        <xsl:param name="pos"/>
        <xsl:value-of select="$pos"/>
</xsl:template>

</xsl:stylesheet>

Current Thread