itom
itom

Reputation: 33

How to write a stylesheet for Xml nested node with attributes?

My question is about display in directions node step like at the end with bold and some info instead "velocity,time and temperature" tags.

XML data example

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="temp.xsl"?>
<records>
    <record>
        <title>Text for title</title>
        <category>Text for category</category>
        <info>Text for info</info>
        <author>Text for author</author>
        <directions>
            <step>Text for simple first step</step>
            <step>Text for complex second step with <time type="seconds">5</time> and <velocity type="clockwise">3</velocity></step>
            <step>Text for complex third step with <time type="minute">3</time> <temperature type="celsius">50</temperature> <velocity type="wheat">1</velocity> </step>
            <step>Text for medium fourth step with <temperature type="celsius">50</temperature> and nothing more</step>
        </directions>
        <notes>
            <note>Text for first note</note>
            <note>Text for second note</note>
        </notes>
    </record>
</records>

temp.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <html>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>
<xsl:template match="record">
    <xsl:apply-templates select="category"/>
    <p>
        <xsl:apply-templates select="title"/>
        <xsl:apply-templates select="info"/>
        <xsl:apply-templates select="author"/>
    </p>
    <h3>Directions</h3>
    <p>
        <ul>
            <xsl:apply-templates select="directions"/>
        </ul>
    </p>
    <h3>Notes</h3>
    <p>
        <ul>
            <xsl:apply-templates select="notes"/>
        </ul>
    </p>
</xsl:template>
<xsl:template match="category">
    <h2>
        <xsl:value-of select="."/>
    </h2>
</xsl:template>
<xsl:template match="title">
    <h3>
        <xsl:value-of select="."/>
    </h3>
</xsl:template>
<xsl:template match="info">
    <xsl:value-of select="."/>
    <br />
</xsl:template>
<xsl:template match="author">
    Author:
    <xsl:value-of select="."/>
    <br />
</xsl:template>
<xsl:template match="directions/step">
    <li>
        <xsl:apply-templates select="time"/>
        <xsl:value-of select="."/>
    </li>
</xsl:template>
<xsl:template match="time">
    <b>time:
        <xsl:value-of select="."/>
    </b>
</xsl:template>
<xsl:template match="notes/note">
    <li>
        <xsl:value-of select="."/>
    </li>
</xsl:template>

Expected output in html:

Text for category

Text for title

Text for info

Directions

Notes

Upvotes: 2

Views: 99

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116992

Change your template matching directions/step to:

<xsl:template match="directions/step">
    <li>
        <xsl:apply-templates/>
    </li>
</xsl:template>

Then add separate templates to handle time, velocity and temperature:

<xsl:template match="time">
    <b>
        <xsl:value-of select="."/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="@type"/>
    </b>
</xsl:template>

<xsl:template match="velocity">
    <b>
        <xsl:text>Speed </xsl:text>
        <xsl:value-of select="."/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="@type"/>
    </b>
</xsl:template>

<xsl:template match="temperature">
    <b>
        <xsl:value-of select="."/>
        <xsl:text>° </xsl:text>
        <xsl:value-of select="translate(substring(@type, 1, 1), 'cfk', 'CFK')"/>
    </b>
</xsl:template>

This way the text nodes, siblings of the three above, will also get processed.

Upvotes: 3

Related Questions