[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Re: How to merge two elements and transform them into a table


Subject: Re: [xsl] Re: How to merge two elements and transform them into a table
From: "Erik Vullings" <erik.vullings@xxxxxxxxx>
Date: Sun, 18 May 2008 00:56:11 +0200

Thanks Jim and Mukul, your solutions worked like a charm!

In the end, I've chosen Jim's XSLTv1.0 solution, since it means that I
don't have to use extensions and can use it in a browser too. I also
learnt a couple of new tricks along the way, so that's great as well.
Especially the recurrency approach will be very useful.

Cheers,
Erik

On Sat, May 17, 2008 at 2:08 PM, James A. Robinson
<jim.robinson@xxxxxxxxxxxx> wrote:
>
> > into a nice HTML page. That works quite well, except for the actor
> > name/role part, which is in two separate nodes for all actors and
> > roles - see the Actors and ActorsRole node below:
>
> One way you could do it is to use positional indexing to map up the
> two -- your example is unfortunate in that xml markup is being mixed
> with an ad-hoc textual markup.  I'm going to assume there is a one to
> one mapping in actors and roles, but if that's not the case then this
> solution would require more thought.
>
> In XSLT 1.0 you could handle this via a recursive template which
> indexes on '|':
>
>  <xsl:template match="Actors">
>    <table>
>      <xsl:call-template name="actor-role">
>          <xsl:with-param name="actors" select="." />
>          <xsl:with-param name="roles"  select="../Actorsrole"  />
>      </xsl:call-template>
>    </table>
>  </xsl:template>
>
>  <xsl:template name="actor-role">
>    <xsl:param name="actors" />
>    <xsl:param name="roles"  />
>
>    <xsl:variable name="actor" select="substring-before($actors, '|')" />
>    <xsl:variable name="next-actors" select="substring-after($actors, '|')" />
>
>    <xsl:variable name="role"  select="substring-before($roles, '|')" />
>    <xsl:variable name="next-roles"  select="substring-after($roles, '|')"  />
>
>    <xsl:if test="normalize-space($actor)">
>      <tr>
>        <td><xsl:value-of select="$actor"/></td>
>        <td><xsl:value-of select="$role"/></td>
>      </tr>
>    </xsl:if>
>
>    <xsl:if test="normalize-space($next-actors)">
>      <xsl:call-template name="actor-role">
>        <xsl:with-param name="actors" select="$next-actors" />
>        <xsl:with-param name="roles"  select="$next-roles"  />
>      </xsl:call-template>
>    </xsl:if>
>  </xsl:template>
>
> In XSLT 2.0 it's easier because you have access to better string
> functions:
>
>  <xsl:template match="Actors">
>    <xsl:variable name="actors" select="tokenize(., '\|')"/>
>    <xsl:variable name="roles"  select="tokenize(../Actorsrole, '\|')"/>
>
>    <table>
>      <xsl:for-each select="$actors[normalize-space()]">
>        <xsl:variable name="i"    select="position()" />
>        <xsl:variable name="role" select="$roles[$i]" />
>        <tr>
>          <td>
>            <xsl:sequence select="."/>
>          </td>
>          <td>
>            <xsl:sequence select="$role"/>
>          </td>
>        </tr>
>      </xsl:for-each>
>    </table>
>  </xsl:template>A
>
> Please note that I'm *not* dealing with namespaces here, I don't
> know if you need xhtml output.
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> James A. Robinson                       jim.robinson@xxxxxxxxxxxx
> Stanford University HighWire Press      http://highwire.stanford.edu/
> +1 650 7237294 (Work)                   +1 650 7259335 (Fax)


Current Thread
Keywords