xsl:if condition

A

Andrea Maschio

Hi, i have a terrible noobie frustration formatting an XML file like
this:

<Dipendente Id="1" Anno="2003" Nome="pippo" Cognome="pippi"
Nato_il="10/03" Email="(e-mail address removed)" Esito="ok"/>

On the XSLt file relayed to this XML, i wrote in green the attribute
value if Attribute "Esito" is "Ok".

I mean, something, like this:

<!--xsl:if test="@Esito != 'Ok' ">
<span style="cursor:hand; font-family:Verdana; font-size:9">
<xsl:value-of select="."/>
</span>
</xsl:if!-->

It seems that the test expression is always evaluated false even if i
set the attribute value to ok, OK, or even anything else. Is there
something wrong with this?

Please Help, I can't get it out!
 
M

Martin Boehm

<!--xsl:if test="@Esito != 'Ok' ">
<span style="cursor:hand; font-family:Verdana; font-size:9">
<xsl:value-of select="."/>
</span>
</xsl:if!-->

Despite the fact that this is a comment and therefore cannot do
_anything_... ;-)

XML is case-sensitive. 'Ok' is different from 'OK' or 'oK'. I think this
causes your trouble.

Four ways to solve it:
1. Make sure it is alwalys 'OK' and nothing else, and
then test for "@Esito != 'OK'"
2. Test for all combinations of capital and non-capital
letters. This is idiotic, but in case your word is only
two chars long, it is still a possibility.
(OK, then it is four possibilities. *g*)
3. Work with a number, if you can.
test="number(@Esito) != 0"
4. Utilize the XPath translate() function to translate
everything into capitals or non-capitals.

Martin
 
A

Andrea Maschio

Despite the fact that this is a comment and therefore cannot do
_anything_... ;-)

Yes, sorry, it was a Typo : )

Ok, that's exactly:

<xsl:if test="number(@Esito) = 0 ">

I tried this solution, setting the value of @Esito to 0, to 1 or anything
else.

Xslt debugger show me the right value, but i can't get to get the test
expression evaluated as True.

Four ways to solve it:
1. Make sure it is alwalys 'OK' and nothing else, and
then test for "@Esito != 'OK'"

I tried that : (
2. Test for all combinations of capital and non-capital
letters. This is idiotic, but in case your word is only
two chars long, it is still a possibility.

Tried also that
(OK, then it is four possibilities. *g*)
3. Work with a number, if you can.
test="number(@Esito) != 0"

I tried
4. Utilize the XPath translate() function to translate
everything into capitals or non-capitals.

I tried also this:

<xsl:when test="string(@Esito) != 'Ok' "> // this is always evaluated true,
despite the value of @Esito

Gosh, i'm sorry, but i'm a newbie, i really don't understand.

THanks for your help

Andrea Maschio
 
M

Martin Boehm

Gosh, i'm sorry, but i'm a newbie, i really don't understand.

I dont, either. I don't know what *exactly* you do, but it works for me:

---test.xml------------------------------------------
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<root>
<Dipendente Id="1" Esito="ok"/>
<Dipendente Id="2" Esito="not ok"/>
<Dipendente Id="3" Esito="ok"/>
</root>
-----------------------------------------------------

combined with...

---test.xsl------------------------------------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<body>
<xsl:apply-templates select="Dipendente"/>
</body>
</xsl:template>
<xsl:template match="Dipendente">
<div>
<xsl:value-of select="@Id"/>
<xsl:text> is </xsl:text>
<xsl:choose>
<xsl:when test="@Esito = 'ok'">
<xsl:value-of select="@Esito"/>
</xsl:when>
<xsl:eek:therwise>
<b><xsl:value-of select="@Esito"/></b>
</xsl:eek:therwise>
</xsl:choose>
</div>
</xsl:template>
</xsl:stylesheet>
-----------------------------------------------------

produces...

---Result--------------------------------------------
<?xml version="1.0" encoding="UTF-16"?>
<body>
<div>1 is ok</div>
<div>2 is
<b>not ok</b>
</div>
<div>3 is ok</div>
</body>
-----------------------------------------------------

This is more or less what you want. If you take the same test (xsl:if or
xsl:when, that makes no difference) and do not get the same result, you
must be in error elsewhere.

Martin
 
A

Andrea Maschio

The problem is exactly that i didn't know how to use templates. I
erroneously though it was enough to apply the condition to every
<xsl:for-each name="Dipendente">.

Now i'm safe from going crazy, phew!

Can you indicate me where i could find a nice tutorial on this
argoment? THe problem was that making xslt with easy editors, i have
not a full control on its processes.

THank you very much for your precious helping!

Andrea
 
M

Martin Boehm

Hi Andrea,
The problem is exactly that i didn't know how to use templates.

I thought so.
I erroneously though it was enough to apply the condition to
every <xsl:for-each name="Dipendente">.

It is <xsl:for-each select... not name ;-)

But I am afraid I still can't picture your problem. Can you post a
example snippet of your XML and XSL?
Can you indicate me where i could find a nice tutorial on this
argoment?

If you only could be a bit more specific. Which argument?
You might want to read into XPath at first. I have no URL at hand, but
Google will.
THe problem was that making xslt with easy editors, i have
not a full control on its processes.

Dump your "easy" editor and use a more appropriate tool (Xselerator from
www.topxml.com has proven to be _very_ useful, if you work in a Windows
environment), or a plain text editor with XML syntax highlighting. At
least if you want to really learn it.

Martin
 
A

Andrea Maschio

The problem is exactly that i didn't know how to use templates.
I thought so.


It is <xsl:for-each select... not name ;-)

It was a Type error, but you are perfectly right: how can you
understand if i don't spell correctly words? : P
But I am afraid I still can't picture your problem. Can you post a
example snippet of your XML and XSL?

My Xml finally worked, elimininating this tag <xsl:for-each
select="NodeName">
and creating a template for this node. After i recall the template
from inside <body></body>. That was right?

Ok, so i thought "Now I Understood!". But I was still not right. I've
got another XML file, it's attached at the end of this post with his
xslt. I was trying to colour a cell only if the relative node is not
empty. In this case still doesn't work.
Dump your "easy" editor and use a more appropriate tool (Xselerator from
www.topxml.com has proven to be _very_ useful, if you work in a Windows
environment), or a plain text editor with XML syntax highlighting. At
least if you want to really learn it.

I surely want to learn this meta language, but like you know,
sometimes it happens you have to work on a tecnology, and then you
have the calm and the time to learn it. I used XMLSPy, with a
stylesheet designer. It seems to me to be very easy to use, but i
don'to know how to set choice upon two conditions, for example.

Here's the file, thanks a lot Martin for your help ^^

------------XML File----------------------------------------------
<!DOCTYPE Import SYSTEM "conti.dtd">
<?xml-stylesheet type="text/xsl" href="stileconti.xslt"?>
<Import>
<Row>
<Data_operazione> 07/10/2003 </Data_operazione>
<Data_valuta> 12/09/2003 </Data_valuta>
<Importo_debito></Importo_debito>
<Importo_credito>9,8</Importo_credito>
<Causale>CausaleText</Causale>
</Row>
<Row>
<Data_operazione> 08/10/2003 </Data_operazione>
<Data_valuta> 09/09/2003 </Data_valuta>
<Importo_debito>30</Importo_debito>
<Importo_credito> </Importo_credito>
<Causale>CausaleText</Causale>
</Row>
</Import>


--------end of XML File---------------------------------------------
------------xslt file----------
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head/>
<body>
<xsl:for-each select="Import">
<xsl:apply-templates select="Row"/>
</xsl:for-each>
</body>
</html>
</xsl:template>

<xsl:template match="Row">
<xsl:if test="position()=1">
<table border="1">
<thead>
<tr>
<td style="background-color:#004080">
<span style="color:white; font-family:Verdana; font-size:9;
font-weight:bold; text-transform:capitalize">Data operazione</span>
</td>
<td style="background-color:#004080">
<span style="color:white; font-family:Verdana; font-size:9;
font-weight:bold; text-transform:capitalize">Data valuta</span>
</td>
<td style="background-color:#004080">
<span style="color:white; font-family:Verdana; font-size:9;
font-weight:bold; text-transform:capitalize">Importo debito</span>
</td>
<td style="background-color:#004080">
<span style="color:white; font-family:Verdana; font-size:9;
font-weight:bold; text-transform:capitalize">Importo credito</span>
</td>
<td style="background-color:#004080">
<span style="color:white; font-family:Verdana; font-size:9;
font-weight:bold; text-transform:capitalize">Causale</span>
</td>
</tr>
</thead>
<tbody>
<xsl:for-each select="../Row">
<tr>
<td style="background-color:#C0C0C0">
<xsl:for-each select="Data_operazione">
<span style="font-family:Verdana; font-size:9">
<xsl:apply-templates/>
</span>
</xsl:for-each>
</td>
<td style="background-color:#D3D3D3">
<xsl:for-each select="Data_valuta">
<span style="font-family:Verdana; font-size:9">
<xsl:apply-templates/>
</span>
</xsl:for-each>
</td>
<td style="background-color:#D90000">
<xsl:for-each select="Importo_debito">
<!--------------------Here it is the "choose"--------------------->
<xsl:choose >
<xsl:when test="Importo_debito != '' ">mycode for coloured
cell</xsl:when>
</xsl:choose>
<!---------------------------------------------------------------->
<span style="color:white; font-family:Verdana;
font-size:9">
<xsl:apply-templates/>
</span>
<xsl:choose><xsl:when test="@Importo_debito != ''
"> </xsl:when></xsl:choose>
</xsl:for-each>
</td>
<td style="background-color:#008000">
<xsl:for-each select="Importo_credito">
<span style="color:#FFFFFF; font-family:Verdana;
font-size:9">
<xsl:apply-templates/>
</span>
</xsl:for-each>
</td>
<td>
<xsl:for-each select="Causale">
<span style="font-family:Verdana; font-size:9;
text-transform:lowercase">
<xsl:apply-templates/>
</span>
</xsl:for-each>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:if>
</xsl:template>

</xsl:stylesheet>
 
P

Patrick TJ McPhee

[...]

% Ok, so i thought "Now I Understood!". But I was still not right. I've
% got another XML file, it's attached at the end of this post with his
% xslt. I was trying to colour a cell only if the relative node is not
% empty. In this case still doesn't work.

[...]

% <!DOCTYPE Import SYSTEM "conti.dtd">
% <?xml-stylesheet type="text/xsl" href="stileconti.xslt"?>
% <Import>
% <Row>
% <Data_operazione> 07/10/2003 </Data_operazione>
% <Data_valuta> 12/09/2003 </Data_valuta>
% <Importo_debito></Importo_debito>
% <Importo_credito>9,8</Importo_credito>
% <Causale>CausaleText</Causale>
% </Row>
% <Row>
% <Data_operazione> 08/10/2003 </Data_operazione>
% <Data_valuta> 09/09/2003 </Data_valuta>
% <Importo_debito>30</Importo_debito>
% <Importo_credito> </Importo_credito>
% <Causale>CausaleText</Causale>
% </Row>
% </Import>

% <?xml version="1.0" encoding="UTF-8"?>
% <xsl:stylesheet version="1.0"
% xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
% <xsl:template match="/">
% <html>
% <head/>
% <body>
% <xsl:for-each select="Import">

It's nothing to do with your problem, but since there can be only one
Import, you don't need this xsl:for-each.

% <xsl:apply-templates select="Row"/>

[...]

% <xsl:for-each select="Importo_debito">
% <!--------------------Here it is the "choose"--------------------->
% <xsl:choose >
% <xsl:when test="Importo_debito != '' ">mycode for coloured
% cell</xsl:when>
% </xsl:choose>
% <!---------------------------------------------------------------->

The problem here is that you're testing inside an xsl:for-each loop.
The context is set to each node returned by the select expression
in turn. What you want is

test = ". != ''"
 
A

Andrea Maschio

The problem here is that you're testing inside an xsl:for-each loop.
The context is set to each node returned by the select expression
in turn. What you want is

test = ". != ''"


Gosh! Now i feel very stupid! I though that in XML this

<node> </node>

was exactly the same as


<node></node>

It's qbvious that the
<xsl:if test ". != '' ">
couldn't work, because it should have been

<xsl:if test ". != ' ' ">

Gosh again..

It's sunday morning 8.pm

thank you very much for helping

Andrea
 
M

Martin Boehm

It's qbvious that the
<xsl:if test ". != '' ">
couldn't work, because it should have been

<xsl:if test ". != ' ' ">

No, it should be
<xsl:if test "normalize-space(.) != ''">

Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top