papastavro
papastavro

Reputation: 61

XSLT FO List elements

my source XML looks like:

<events>
  <entry>
      <event>Event 1</event>
      <event>Event 2</event>
      <event>Event 3</event>
      <event>Event 4</event>
    </entry>
</events>

Here is the corresponding code of my XSL transformation:

<fo:block-container>
  <fo:list-block>
    <xsl:for-each select="//event">
      <fo:list-item> 
         <fo:list-item-label/>
           <fo:list-item-body>
              <fo:block>
                <xsl:value-of select="//event"/>
              </fo:block>
           </fo:list-item-body>  
      </fo:list-item>
    </xsl:for-each>
  </fo:list-block>
</fo:block-container>

And the FO output:

<fo:list-block>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 1Event 2Event 3Event 4</fo:block>
      </fo:list-item-body>
  </fo:list-item>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 1Event 2Event 3Event 4</fo:block>
      </fo:list-item-body>
  </fo:list-item>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 1Event 2Event 3Event 4</fo:block>
      </fo:list-item-body>
  </fo:list-item>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 1Event 2Event 3Event 4</fo:block>
      </fo:list-item-body>
  </fo:list-item>

My problem is that each of the event elements should be transformed into a separate fo:list-item, like:

<fo:list-block>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 1</fo:block>
      </fo:list-item-body>
  </fo:list-item>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 2</fo:block>
      </fo:list-item-body>
  </fo:list-item>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 3</fo:block>
      </fo:list-item-body>
  </fo:list-item>
  <fo:list-item>
    <fo:list-item-label/>
      <fo:list-item-body>
        <fo:block>Event 4</fo:block>
      </fo:list-item-body>
  </fo:list-item>

I hope you can help me out...

Upvotes: 2

Views: 1719

Answers (2)

Tomalak
Tomalak

Reputation: 338376

Instead of

<xsl:value-of select="//event"/>

use

<xsl:value-of select="."/>

You want to output the current event, after all, not all of them.


In more general terms, I recommend changing your XSLT program away from a <xsl:for-each> towards a <xsl:template>/<xsl:apply-templates> based form:

<xsl:template match="events">
  <fo:block-container>
    <xsl:apply-templates />
  </fo:block-container>
</xsl:template>

<xsl:template match="events/entry">
  <fo:list-block>
    <xsl:apply-templates />
  <fo:list-block>
</xsl:template>

<xsl:template match="events/entry/event">
  <fo:list-item> 
    <fo:list-item-label/>
    <fo:list-item-body>
      <fo:block>
        <xsl:value-of select="."/>
      </fo:block>
    </fo:list-item-body>  
  </fo:list-item>
</xsl:template>

This approach is more modular, has better re-usability and is overall not as deeply nested.

Upvotes: 4

Martin Honnen
Martin Honnen

Reputation: 167716

Replace <xsl:value-of select="//event"/> with <xsl:value-of select="."/> as inside the for-each the event element is the context node.

Upvotes: 1

Related Questions