tags:

views:

39

answers:

3

I'm having a slightly odd situation with an XSL template. Most of it outputs fine, but a certain for-each loop is causing me problems.

Here's the XML:

<area>
<feature type="Hall">
    <Heading><![CDATA[Hall]]></Heading> 
    <Para><![CDATA[Communal gardens, pathway leading to PVCu double glazed communal front door to]]></Para> 
</feature>
<feature type="Entrance Hall">
    <Heading><![CDATA[Communal Entrance Hall]]></Heading> 
    <Para><![CDATA[Plain ceiling, centre light fitting, fire door through to inner hallway, wood and glazed panelled front door to]]></Para> 
</feature>
<feature type="Inner Hall">
    <Heading><![CDATA[Inner Hall]]></Heading> 
    <Para><![CDATA[Plain ceiling with pendant light fitting and covings, security telephone, airing cupboard housing gas boiler serving domestic hot water and central heating, telephone point, storage cupboard housing gas and electric meters, wooden panelled doors off to all rooms.]]></Para> 
</feature>
<feature type="Lounge (Reception)" width="3.05" length="4.57" units="metre">
    <Heading><![CDATA[Lounge (Reception)]]></Heading> 
    <Para><![CDATA[15' 6" x 10' 7" (4.72m x 3.23m) Window to the side and rear elevation, papered ceiling with pendant light fitting and covings, two double panelled radiators, power points, wall mounted security entry phone, TV aerial point.]]></Para> 
</feature>
<feature type="Kitchen" width="3.05" length="3.66" units="metre">
    <Heading><![CDATA[Kitchen]]></Heading> 
    <Para><![CDATA[12'  x 10'  (3.66m x 3.05m) Double glazed window to the rear elevation, textured ceiling with strip lighting, range of base and wall units in Beech with brushed aluminium handles, co-ordinated working surfaces with inset stainless steel sink with mixer taps over, co-ordinated tiled splashbacks, gas and electric cooker points, large storage cupboard with shelving, power points.]]></Para> 
</feature>
<feature type="Entrance Porch">
    <Heading><![CDATA[Balcony]]></Heading> 
    <Para><![CDATA[Views across the communal South facing garden, wrought iron balustrade.]]></Para> 
</feature>
<feature type="Bedroom" width="3.35" length="3.96" units="metre">
    <Heading><![CDATA[Bedroom One]]></Heading> 
    <Para><![CDATA[13' 6" x 11' 5" (4.11m x 3.48m) Double glazed windows to the front and side elevations, papered ceiling with pendant light fittings and covings, single panelled radiator, power points, telephone point, security entry phone.]]></Para> 
</feature>
<feature type="Bedroom" width="3.05" length="3.35" units="metre">
    <Heading><![CDATA[Bedroom Two]]></Heading> 
    <Para><![CDATA[11' 4" x 10' 1" (3.45m x 3.07m) Double glazed window to the front elevation, plain ceiling with centre light fitting and covings, power points.]]></Para> 
</feature>
<feature type="bathroom">
    <Heading><![CDATA[Bathroom]]></Heading> 
    <Para><![CDATA[Obscure double glazed window to the rear elevation, textured ceiling with centre light fitting and extractor fan, suite in white comprising of low level WC, wall mounted wash hand basin and walk in shower housing 'Triton T80' electric shower, co-ordinated tiled splashbacks.]]></Para> 
</feature>
</area>

And here's the section of my template that processes it:

<xsl:for-each select="area">
    <li>
        <xsl:for-each select="feature">
            <li>
                <h5>
                    <xsl:value-of select="Heading"/>
                </h5>
                <xsl:value-of select="Para"/>
            </li>
        </xsl:for-each>
    </li>
</xsl:for-each>

And here's the output:

Hall Communal gardens, pathway leading to PVCu double glazed communal front door to Communal Entrance Hall Plain ceiling, centre light fitting, fire door through to inner hallway, wood and glazed panelled front door to Inner Hall Plain ceiling with pendant light fitting and covings, security telephone, airing cupboard housing gas boiler serving domestic hot water and central heating, telephone point, storage cupboard housing gas and electric meters, wooden panelled doors off to all rooms. Lounge (Reception) 15' 6" x 10' 7" (4.72m x 3.23m) Window to the side and rear elevation, papered ceiling with pendant light fitting and covings, two double panelled radiators, power points, wall mounted security entry phone, TV aerial point. Kitchen 12' x 10' (3.66m x 3.05m) Double glazed window to the rear elevation, textured ceiling with strip lighting, range of base and wall units in Beech with brushed aluminium handles, co-ordinated working surfaces with inset stainless steel sink with mixer taps over, co-ordinated tiled splashbacks, gas and electric cooker points, large storage cupboard with shelving, power points. Balcony Views across the communal South facing garden, wrought iron balustrade. Bedroom One 13' 6" x 11' 5" (4.11m x 3.48m) Double glazed windows to the front and side elevations, papered ceiling with pendant light fittings and covings, single panelled radiator, power points, telephone point, security entry phone. Bedroom Two 11' 4" x 10' 1" (3.45m x 3.07m) Double glazed window to the front elevation, plain ceiling with centre light fitting and covings, power points. Bathroom Obscure double glazed window to the rear elevation, textured ceiling with centre light fitting and extractor fan, suite in white comprising of low level WC, wall mounted wash hand basin and walk in shower housing 'Triton T80' electric shower, co-ordinated tiled splashbacks.

For reference, here's the entire XSLT: http://pastie.org/private/eq4gjvqoc1amg9ynyf6wzg

EDIT: And here's the full XML: http://pastie.org/private/upu3g9rstw8pilemtaq

The rest of it all outputs fine - what am I missing from the above section?

+5  A: 

You shouldn't be using xsl:for-each everywhere, but templates:

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

    <xsl:template match="feature">
        <li>
            <h5>
                <xsl:value-of select="Heading"/>
            </h5>
            <xsl:value-of select="Para"/>
        </li>
    </xsl:template>

I am guessing that none of your matching rules actually get called so the default template gets invoked (this template simply outputs all text, as you describe).

Read Understanding How the Default Templates Work for more information.

Update:

The root cause of the problem, as discovered by Stephen Denne, is that your area element is wrapped in a text element, so was never selected, causing the the default template to be called, outputting the text nodes.

Oded
Why are all the tag contents in CDATA tags? It seems like overkill.
scunliffe
@scunliffe, Wish I bloody knew, it's not my XML - it's a feed from a client's system.
Throlkim
@oded, Thanks for the advice - it's been a while since I did XSL. After switching it over to templates I'm still having the same issue - could it be to do with the CDATA tags?
Throlkim
Definitely recommend templates over for-each loops.
Mads Hansen
@Throlkim - the match on the top template (match="property") should be changed to match on the root node: `match="/"`.
Oded
Updated with full XML - my apologies for not posting it earlier; it might help solve some confusion over the root element etc.
Throlkim
+1 I would specifically do `<xsl:apply-templates select="feature" />` since doing so disambiguates the stylesheet a lot and reduces unwanted whitespace in the output.
Tomalak
Why all the CDATA? If you're working with a system which doesn't have a proper XML serializer, it's easier to use CDATA sections for every text node rather than to try implementing the XML escaping rules in your own code.
Paul Clapham
A: 

Your stylesheet has a template that matches on property, but there is no property element in your XML for it to match on.

So, the default template rules are matching, which emit the text nodes.

If you change your template from a match on property:

<xsl:template match="property">

To a match on the root node:

<xsl:template match="/">

You get the following output, which I think is what you want:

<ul id="property" xmlns:php="http://php.net/xsl"&gt;
<li>
<ul class="pictures"></ul>
</li>
<li>
<address></address>
</li>
<li>
                Price: </li>
<li>
<li>
<h5>Hall</h5>Communal gardens, pathway leading to PVCu double glazed communal front door to</li>
<li>
<h5>Communal Entrance Hall</h5>Plain ceiling, centre light fitting, fire door through to inner hallway, wood and glazed panelled front door to</li>
<li>
<h5>Inner Hall</h5>Plain ceiling with pendant light fitting and covings, security telephone, airing cupboard housing gas boiler serving domestic hot water and central heating, telephone point, storage cupboard housing gas and electric meters, wooden panelled doors off to all rooms.</li>
<li>
<h5>Lounge (Reception)</h5>15' 6" x 10' 7" (4.72m x 3.23m) Window to the side and rear elevation, papered ceiling with pendant light fitting and covings, two double panelled radiators, power points, wall mounted security entry phone, TV aerial point.</li>
<li>
<h5>Kitchen</h5>12'  x 10'  (3.66m x 3.05m) Double glazed window to the rear elevation, textured ceiling with strip lighting, range of base and wall units in Beech with brushed aluminium handles, co-ordinated working surfaces with inset stainless steel sink with mixer taps over, co-ordinated tiled splashbacks, gas and electric cooker points, large storage cupboard with shelving, power points.</li>
<li>
<h5>Balcony</h5>Views across the communal South facing garden, wrought iron balustrade.</li>
<li>
<h5>Bedroom One</h5>13' 6" x 11' 5" (4.11m x 3.48m) Double glazed windows to the front and side elevations, papered ceiling with pendant light fittings and covings, single panelled radiator, power points, telephone point, security entry phone.</li>
<li>
<h5>Bedroom Two</h5>11' 4" x 10' 1" (3.45m x 3.07m) Double glazed window to the front elevation, plain ceiling with centre light fitting and covings, power points.</li>
<li>
<h5>Bathroom</h5>Obscure double glazed window to the rear elevation, textured ceiling with centre light fitting and extractor fan, suite in white comprising of low level WC, wall mounted wash hand basin and walk in shower housing 'Triton T80' electric shower, co-ordinated tiled splashbacks.</li>
</li>
</ul>
Mads Hansen
Ah, my bad for not posting the full XML file. I've added it to the end of the question - very sorry for any confusion.
Throlkim
+1  A: 

Your area element is inside your text element.

Stephen Denne
You have sharp eyes - I totally missed that. Thanks very much :) (can you blame me for missing it with that XML formatting though? / **shudder**)
Throlkim