BernatL
BernatL

Reputation: 72

XSLT - Dynamic nesting of elements

I'm working on a stylesheet that outputs HTML from XML inputs. I have to generate different nesting levels in the output file according to the position of a list of elements in the input. For instance, NEWS[1] and NEWS[2] should be nested under same element as well as NEWS[3] and NEWS[4].

This is an example of XML input:

<NEWS_LIST>
    <NEWS>
        <TITLE>Title of the notice #1</TILE>
        <IMG_URL>http://media/image_1.png</IMG_URL>
    </NEWS>
    <NEWS>
        <TITLE>Title of the notice #2</TILE>
        <IMG_URL>http://media/image_2.png</IMG_URL>
    </NEWS>
    <NEWS>
        <TITLE>Title of the notice #3</TILE>
        <IMG_URL>http://media/image_3.png</IMG_URL>
    </NEWS>
    <NEWS>
        <TITLE>Title of the notice #4</TILE>
        <IMG_URL>http://media/image_4.png</IMG_URL>
    </NEWS>
</NEWS_LIST>

Desired HTML output:

<div class="middle>
    <div class="unit 1">
        <div class="unit 2">
            <img src="http://media/image_1.png"/>
            <p>Title of the notice #1</p>
        </div>
        <div class="unit 2">
            <img src="http://media/image_2.png"/>
            <p>Title of the notice #2</p>
        </div>
    </div>
    <div class="unit 1">
        <div class="unit 2">
            <img src="http://media/image_3.png"/>
            <p>Title of the notice #3</p>
        </div>
        </div class="unit 2">
            <img src="http://media/image_4.png"/>
            <p>Title of the notice #4</p>
        </div>
    </div>
</div>

I am using XSLT position() function to select elements and to output files but I don't know how to nest childs. Any help would be really appreciated.

Upvotes: 0

Views: 142

Answers (1)

Little Santi
Little Santi

Reputation: 8783

I suggest you browse the NEWS nodes in two phases:

    1. First phase: Match all the odd position nodes: <xsl:apply-templates select="NEWS[(position() mod 2)=1]" mode="unit1"/>

    ...and for each one, apply the second phase to it and to the next one: <xsl:template match="NEWS" mode="unit1"> <div class="unit 1"> <xsl:apply-templates select="." mode="unit2"></xsl:apply-templates> <xsl:apply-templates select="following-sibling::NEWS[1]" mode="unit2"/> </ div> </xsl:template>

    1. Second phase: Print each node processed. <xsl:template match="NEWS" mode="unit2"> <div class="unit 2"> <img src="{IMG_URL}" /> <p><xsl:value-of select="TITLE"/></p> </ div> </xsl:template>

Note that there are two templates matching NEWS, but they differ in the mode (which is proper for each phase).

Upvotes: 1

Related Questions