MIlena
MIlena

Reputation: 257

How to use xslt to format inner nodes while you also need to format the outer node?

I have the following xml:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="ping1.xsl"?>
<article>
    <date>28/06/2000 12:30</date>
    <title>Rescued penguins swim home</title>
    <para><place>Cape Town</place> Some 150 penguins unaffected by the oil spill began
    their long swim from Port Elizabeth in the Eastern Cape back to their breeding
    habitat at Robben Island near Cape Town on Wednesday. </para>
    <para>The penguins, who have all been tagged, were transported in a truck hired by
    the <company>South African National Conservation of Coastal Birds
    (Sanccob)</company> to Port Elizabeth on Tuesday night. </para>
    <para>More than <link ref="www.newsrus.com/oilspill.html">400 tons of fuel oil
    escaped from the bulk ore carrier Treasure</link> before divers were able to seal
    the holds.</para>
    <para>The ship was carrying 130 000 tons of iron ore and 1 300 tons of fuel oil
    when she sank off the Cape West coast last Friday. </para>
    <para>A spokesperson for <company>Sanccob</company>, Christina Pretorius said
    the centre had a capacity to treat 1 000 penguins. </para>
    <source>John Rolfe</source>
</article>

I need to transform it in the following html form (you have the image of the HTML form):

enter image description here

The problem is I don't know how to apply templates on the para element and its sons element to get the output described in the image above. Till now I have only:

    <?xml version="1.0" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"  encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
    <xsl:template match='/'>
        <HTML>
            <BODY>
                <xsl:apply-templates /> 
            </BODY>
        </HTML>
    </xsl:template>
    <xsl:template match="date">
        <b><xsl:value-of select="."/></b>
        <br/>   
    </xsl:template>
    <xsl:template match="title">
        <font color="blue"><xsl:value-of select="."/></font>
        <br/>
        <br/>
    </xsl:template>
    <xsl:template match="para">
        <xsl:value-of select="."/><br/>
    </xsl:template>
</xsl:stylesheet>

PS: I don't really care about the exact html style. You can also make it much more simplier. I just need to know how to apply templates to the para element and its sons and have the output as described in the image. PS2: No for-each is allowed. Only templates and apply-templates. It is an exercise with respect to an assignment and it asks minimal use of templates and no for-each

Upvotes: 0

Views: 55

Answers (2)

matthias_h
matthias_h

Reputation: 11416

Because you mentioned that it's an exercise, I wouldn't like to give a full solution, but maybe something you can work with: when you add the following templates (and replacing the <xsl:template match="para">) to your XSLT

<xsl:template match="para">
  <p>
    <xsl:apply-templates />
  </p>
</xsl:template>
<xsl:template match="link">
 <a>
   <xsl:attribute name="href" select="@ref"/>
     <xsl:apply-templates />
 </a>
</xsl:template>
<xsl:template match="company | source">
  <span style="font-weight:bold; font-style:normal;">
    <xsl:apply-templates /> 
  </span>
</xsl:template>

this output (only part of it as example) is created:

<p>The penguins, who have all been tagged, were transported in a truck hired by the 
<span style="font-weight:bold; font-style:normal;">South African National Conservation 
 of Coastal Birds (Sanccob)</span> to Port Elizabeth on Tuesday night. 
</p>
<p>More than <a href="www.newsrus.com/oilspill.html">400 tons of fuel oil escaped 
from the bulk ore carrier Treasure</a> before divers were able to seal the holds.
</p>

The template matching para creates a <p> element and applies templates to the content of the para element. The template matching link creates an <a> tag with the href value of the ref attribute. The template matching company and source elements creates a <span> with a bold and normal font style (here you could also use css classes instead of inline styles), as most of the copy in the desired output is italic.
So you can just use templates matching the input elements to create HTML tags and apply the appropriate inline styles or add classes to get the desired output.

Upvotes: 0

malarres
malarres

Reputation: 2946

It seems that you need to use <xsl:for-each> inside the <xsl:template match="para">

e.g.:

<xsl:for-each select="place">

(of course this is not the only solution, but it is what it comes to my mind)

Upvotes: 1

Related Questions