Forum Moderators: open

Message Too Old, No Replies

XSL : list of items from a newspage and their descriptions

howto skip code from being created if element is empty or nonexistant?

         

Darkelve

2:30 pm on Dec 6, 2004 (gmt 0)

10+ Year Member



In another post, I solved my problem on how to list several newsitems in a 'quick news' section:
[webmasterworld.com...]

Now in the same page, a set of anchors gives a list of the titles of all articles on the page; each anchor refers to the corresponding bookmark with a more complete description of the article.

The XML file I use for the 'quick news' section (nieuwslijn) will hold the data for the main content of rest of this page (middle column) as well.

I am planning on coding it something like this (pseudo-code):


<xsl:for-each select="nieuwslijn/artikel">
<a href="#{value_of_anchor}">(Value_of_title)</a>
...

<a name="{value_of_anchor}"></a>
<h2>(Value_of_title)</h2>
<h3><em>(Value_of_date)</em></h3>
<h3>(Value_of_subtitle)</h3>
<p>(Value_of_description)</p> --> Paragraph 1
<p>paragraph 2 content</p> --> Paragraph 2
<p>Paragraph X</p>

<p class="naarboven" align="right"><a href="#boven">naar boven</a></p>

</xsl:for-each>

But my problem is that, some elements might be empty or non-existant (e.g. not every article will have a subtitle). In that case, no code should be produced.

So how do I specify is XSL that when an element is empty (best approach in this case I think), no code should be produced?

[edited by: tedster at 6:51 pm (utc) on Jan. 2, 2005]

Alternative Future

2:36 pm on Dec 6, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi Darkelve,

Something like this:

<xsl:choose>
<xsl:when test="Value_of_subtitle!= ''">
//show your subtitle
</xsl:when>
<xsl:otherwise>
//else show nothing
</xsl:otherwise>
</xsl:choose>

If you have smillys switched on then it should be <xsl: otherwise> without the whitespace
And the not equal to!= checks single quotes ' '

HTH,

-George

[edited by: tedster at 6:51 pm (utc) on Jan. 2, 2005]
[edit reason] disable graphic smile faces [/edit]

Darkelve

10:53 am on Dec 9, 2004 (gmt 0)

10+ Year Member



My current XSL code:


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<ul>
<xsl:for-each select="nieuwslijn/artikel/omschrijving">
<li><a href="#{anker}"><xsl:value-of select="titel"/></a></li>
</xsl:for-each>
</ul>

<xsl:for-each select="nieuwslijn/artikel/omschrijving">
<a name="{anker}"></a>
<h2><xsl:value-of select="titel"/></h2>
<h3><em><xsl:value-of select="datum"/></em></h3>
<h3><xsl:value-of select="subtitel"/></h3>

<xsl:choose>
<xsl:when test="afbeelding!=''">
<div align="{afbeelding/align}">
<img src="{afbeelding/src}" alt="{afbeelding/alt}" />
</div>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>

<xsl:choose>
<xsl:when test="paragraaf!=''">
<p>
<xsl:value-of select="paragraaf"/>
</p>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>

<p class="naarboven" align="right"><a href="#boven">naar boven</a></p>

</xsl:for-each>

</xsl:template>
</xsl:stylesheet>

My current XML code:


<nieuwslijn>

<artikel id="1">
<titel>de nieuwslijn</titel>
<datum>25 november 2004</datum>
<inhoud>Dienstregelingen en wedstrijd oudejaarsnacht beschikbaar vanaf 6 december</inhoud>
<internetadres>http://www.example.com/nieuws/.#oudejaarsnacht</internetadres>
<style_identifier>newsitem</style_identifier>
<omschrijving>
<titel>Dienstregelingen en wedstrijd oudejaarsnacht beschikbaar vanaf 6 december</titel>
<datum>25 november 2004</datum>
<subtitel></subtitel>
<paragraaf id="1">Vanaf 6 december 2004 kunt u op deze website terecht voor de dienstregelingen en de wedstrijd voor oudejaarsnacht.</paragraaf>
<anker>oudejaarsnacht</anker>
</omschrijving>

</artikel>

<artikel id="2">
<titel>de nieuwslijn</titel>
<datum>26 november 2004</datum>
<inhoud>Tentoonstelling '100 jaar elektrische tram' nog tot 9 januari</inhoud>
<internetadres>http://www.delijn.be/oostvlaanderen/evenementen_elektrischetram.html</internetadres>
<style_identifier>endnewsitem</style_identifier>

<omschrijving>
<titel>22 september 2004: Europese dag 'Zonder Auto mobiel in de stad!'</titel>
<datum>9 september 2004</datum>
<subtitel>Voor 1 euro de hele dag mobiel</subtitel>
<paragraaf id="1">Elk jaar spannen een aantal grote Vlaamse steden zich in om hun straten op 22 september autovrij te maken. De Lijn steunt dit initiatief: daarom reist u op deze Europese dag zonder auto voor 1 euro. Met dit 1 euro-biljet mag u de hele dag gebruik maken van alle bussen en trams van De Lijn.</paragraaf>
<anker>carfreeday</anker>
</omschrijving>
</artikel>

<artikel id="3">
<titel>de nieuwslijn</titel>
<datum></datum>
<inhoud>1e Vlaams initiatief autodelen start in Gent</inhoud>
<internetadres>http://www.delijn.be/nieuws/#autodelen</internetadres>
<style_identifier>newsitem</style_identifier>
<omschrijving>
<titel>1e Vlaams initiatief autodelen start in Gent</titel>
<datum></datum>
<subtitel>TestAutodelen</subtitel>

<afbeelding>
<src>/images/subimages/banner_buzzy.gif</src>
<alt>Banner Buzzy</alt>
<border>0</border>
<width>195</width>
<height>120</height>
<align>center</align>
</afbeelding>

<paragraaf>Autodelen is een systeem waarbij een aantal auto's op verschillende plaatsen in een stad (of meerdere steden) ter beschikking staan van mensen die op het systeem aangesloten zijn. Wie klant is, kan tegen een vergoeding 1 van deze wagens gebruiken wanneer hij er 1 nodig heeft. Naast een kleine maandelijkse bijdrage betaalt een cambio-klant alleen een vergoeding voor het aantal afgelegde kilometers en de tijd dat het voertuig werd gebruikt.</paragraaf>

<paragraaf>Test2</paragraaf>
<paragraaf>Test3</paragraaf>
<anker>autodelen</anker>
</omschrijving>
</artikel>

</nieuwslijn>

It shows the first instance of <paragraaf> allright, and doesn't produce anything if there is nothing there, but what I want to do is process the next instances and stop when the last instance has been reached, because there could be multiple paragraphs. E.g. the paragraphs containing the text "Test2" an "Test3" should be selected and displayed on screen as well.

I also added some code to insert an image, but that has nothing to do with this question.

[edited by: tedster at 6:54 pm (utc) on Jan. 2, 2005]
[edit reason] Disable graphic smiles, use example [/edit]

Alternative Future

11:03 am on Dec 9, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi Darkelve,

Not sure I follow, but here is a stab at it. You are creating a for-each to each article within each article there can be one or more paragraaf's yeah?

<xsl:for-each select="nieuwslijn/artikel/omschrijving">
//your current xpaths remain here

<xsl:for-each select="paragraaf">
<xsl:choose>
<xsl:when test=".!=''">
<p><xsl:value-of select="."/></p>
</xsl:when>
<xsl: otherwise>
</xsl: otherwise>
<xsl:for-each>

You can create a for-each (paragraaf) within a for-each (articles) your conditional check then checks the root of paragraaf with . for null or empty string value.

HTH,

-george

Darkelve

11:29 am on Dec 9, 2004 (gmt 0)

10+ Year Member



I created a quick 'hack' around the problem, it works this way, but it's not that flexible... ideally it should be inside some kind of loop:

XML code that matters:


<paragraaf id="1">Autodelen is een systeem waarbij een aantal auto's op verschillende plaatsen in een stad (of meerdere steden) ter beschikking staan van mensen die op het systeem aangesloten zijn. Wie klant is, kan tegen een vergoeding 1 van deze wagens gebruiken wanneer hij er 1 nodig heeft. Naast een kleine maandelijkse bijdrage betaalt een cambio-klant alleen een vergoeding voor het aantal afgelegde kilometers en de tijd dat het voertuig werd gebruikt.</paragraaf>
<paragraaf id="2">Test2</paragraaf>
<paragraaf id="3">Test3</paragraaf>

XSL code that matters:


<xsl:choose>
<xsl:when test="paragraaf[@id='1']!=''">
<p><xsl:value-of select="paragraaf[@id='1']"/></p>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>

<xsl:choose>
<xsl:when test="paragraaf[@id='2']!=''">
<p><xsl:value-of select="paragraaf[@id='2']"/></p>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>

<xsl:choose>
<xsl:when test="paragraaf[@id='3']!=''">
<p><xsl:value-of select="paragraaf[@id='3']"/></p>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>

Instead of specifying each id="x" seperately, I'd like to make it so that it checks each attribute nr. and stops when there are none left (when the last element has been reached).

This is the only functionality I am still missing for this page.

[edited by: tedster at 6:55 pm (utc) on Jan. 2, 2005]
[edit reason] Disable graphic smile faces [/edit]

Alternative Future

11:36 am on Dec 9, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Darkelve,

What was wrong with the suggested loop within a loop I posted above? It does what you are after and also checks for an empty string, without repeating your conditional statements.

-George

Darkelve

11:56 am on Dec 9, 2004 (gmt 0)

10+ Year Member



I got an XML error message in my browser... maybe I used wrong nesting somewhere; it was kind of confusing since I couldn't determine where to put the </xsl:for-each> tag.

I'll try to get it right.

Alternative Future

12:54 pm on Dec 9, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi Darkelve,

The for-each would be located within the node element that contains the one or more paragraaf's.

So where you are looping around each of the articles with xsl:for-each from your data island you have one or more of these. Within your loop of articles you would again have another xsl:for-each of the paragraaf's. Hope this makes sense.

-George