[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Re: How to merge two elements and transform them i

Subject: Re: Re: How to merge two elements and transform them into a table
From: "James A. Robinson" <jim.robinson@xxxxxxxxxxxx>
Date: Sat, 17 May 2008 05:08:24 -0700
Re:  Re: How to merge two elements and transform them i
> 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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.