iswinky
iswinky

Reputation: 1969

Looping results in xsl-fo with same node

I'm having trouble correctly displaying the select values in a loop using xsl-fo.

As you can see in the xml there are a number of <visited> nodes for each <firstname>. I'm trying to display each <visited> value in an fo:block tag, but at the moment it just displays them all on the one fo:block which causes the values to squash together all on one line and I can't figure it out.

XSL:

<xsl:template match="/">
    <xsl:for-each select="company/staff">
        <fo:block>
            <xsl:value-of select="@id" />
        </fo:block>

        <xsl:for-each select="firstname">
            <fo:block>
                <xsl:value-of select="@name" />
            </fo:block>

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

        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

XML:

<company>
    <staff id="1">
        <firstname name="name_1">
            <visited>location_1</visited>
            <visited>location_2</visited>
            <visited>location_3</visited>
            <visited>location_4</visited>
            ...
        </firstname>
        <firstname name="name_2">
            <visited>location_1</visited>
            ...
        </firstname>
    </staff>
    <staff id="2">
        ...
    </staff>
</company>

Upvotes: 0

Views: 539

Answers (2)

Tony Graham
Tony Graham

Reputation: 8068

Let the XSLT processor do the work for you and also be more resilient to possible future changes in the XML:

<xsl:strip-space elements="*"/>

<xsl:template match="staff">
  <fo:block>
     <xsl:value-of select="@id" />
  </fo:block>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="firstname">
  <fo:block>
    <xsl:value-of select="@name" />
  </fo:block>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="visited">
  <fo:block>
     <xsl:value-of select="." />
  </fo:block>
</xsl:template>

Upvotes: 1

Tim C
Tim C

Reputation: 70648

You need to wrap the code that currently outputs the fo:block in an xsl:for-each so that it applies to each separate visited node, not just the first:

    <xsl:for-each select="firstname">
        <fo:block>
            <xsl:value-of select="@name" />
        </fo:block>

        <xsl:for-each select="visited">
            <fo:block>
                <xsl:value-of select="." />
            </fo:block>
         </xsl:for-each>
    </xsl:for-each>

Upvotes: 1

Related Questions