xsl-list
[Top] [All Lists]

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

2008-05-17 05:08:54
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(_dot_)robinson(_at_)stanford(_dot_)edu
Stanford University HighWire Press      http://highwire.stanford.edu/
+1 650 7237294 (Work)                   +1 650 7259335 (Fax)

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>