PDA

View Full Version : xsl:if statements


TheJoey
04-18-2010, 10:37 AM
<xml>
<bookname> google </bookname>
<bookname> doodle </blookname>
<bookname> koodle </bookname>

</xml>

i want to create a if statement in xsl:if that would get the firstletter of the bookname and create a attribute bookname="g"

thanks

Dormilich
04-18-2010, 07:00 PM
what do you need an if statement for?

for extracting the first letter use XSLT's string functions (substring())

TheJoey
04-19-2010, 03:41 AM
so it would be
<xsl:element name="bookname" <xsl:value-of select="substring([1])"/> </xsl:element>

this would get the first sentence wouldnt it?

Dormilich
04-19-2010, 07:38 AM
nope. see here (http://www.w3.org/TR/xpath/#function-substring) how the substring function is called.

TheJoey
04-19-2010, 08:00 AM
that way i have to input all the strings, isnt there a way i can get it automatically?

thought it might be possible with an array, could you provide an example, might it be possible like this
#

substring(bookname(".", .*)

Dormilich
04-19-2010, 08:04 AM
the first parameter of substring() must evaluate as string, that is, every valid XPath giving you a string will do (i.e. no lists).
example
<xsl:value-of select="substring(., 5, 2)"/>

TheJoey
04-19-2010, 08:11 AM
just dont understand how i can use that to get the first letter to apply it to an attribute...


<xsl:element name="bookname"><xsl:value-of select="substring(., 5, 2)"/></xsl:element> stuck at the (.,5,2) part

<xml>
<bookname> google </bookname>
<bookname> doodle </blookname>
<bookname> koodle </bookname>

</xml>
xpath isnt my strongest point and neither is the regex, but where im stuck is how do i exclude the rest of the string except for that first character?

Returns the substring from the start position to the specified length. Index of the first character is 1. If length is omitted it returns the substring from the start position to the end

Example: substring('Beatles',1,4)
Result: 'Beat'

Example: substring('Beatles',2)
Result: 'eatles'
this explained it alot but is there a 1, 1, * way of doing it?

Dormilich
04-19-2010, 09:06 AM
substring('Beatles',1,1) => "B"

what the XPath looks like depends on your XSL.

TheJoey
04-19-2010, 09:34 AM
So if i keep it
<xsl:element name="bookname"><xsl:value-of select="substring(1,1)"/></xsl:element>

so how would i then apply that to an attribute, would i just change the xsl:element to xsl:attribute name="bookname" type="firstletter"

Dormilich
04-19-2010, 09:36 AM
so how would i then apply that to an attribute, would i just change the xsl:element to xsl:attribute

yes.

again, the substring() function expects a string/string node to be passed explicitly.

TheJoey
04-19-2010, 09:40 AM
<xsl:for-each>
<xsl:element name="bookname"><xsl:attribute name="firstletter"><xsl:value-of select="substring(1,1)"/></xsl:attribute></xsl:element>
</xsl:for-each>

theorettly would work, could this be applied

TheJoey
04-19-2010, 10:44 AM
<xsl:for-each>
<xsl:element name="bookname"><xsl:attribute name="firstletter"><xsl:value-of select="substring(1,1)"/></xsl:attribute></xsl:element>
</xsl:for-each>

theorettly would work, could this be applied

What i meant to say was if xsl:for-each and my attribute name settings are applied correctly?

Dormilich
04-19-2010, 10:56 AM
first, get yourself an XSLT reference (e.g. w3schools [1] (http://w3schools.com/xsl/xsl_w3celementref.asp) and w3schools [2] (http://w3schools.com/xpath/xpath_functions.asp))

neither the call of <xsl:for-each>, nor substring() is correct.

I’d probably prefer <xsl:template> over <xsl:for-each>, but that depends on the whole picture.

TheJoey
04-19-2010, 11:00 AM
I seem to read them, over and over.. but when it comes to applying to my xml, i cant do it.

reading that, i notice that the foreach isnt needed.
and the substring, is what im asking for help in as i do not know how to "automaticaly" identify the value within the <bookname>.

i was reading that substring beatles example before hand

edit: substring(bookname,1,1) i need something along this line

Dormilich
04-19-2010, 11:05 AM
and the substring, is what im asking for help in as i do not know how to "automaticaly" identify the value within the <bookname>.

all you need (instead of "Beatles") is a valid XPath. but since I don’t know your XSL file, I can’t tell you what the XPath should be, because that depends on how you call it.

for instance
<xsl:template match="bookname">
<xsl:element name="whatever">
<xsl:attribute name="local-name()">
<xsl:value-of select="substring(./text(), 1, 1)"/>
</xsl:atribute>
</xsl:element>
</xsl:template>
would probably work

TheJoey
04-19-2010, 11:11 AM
all you need (instead of "Beatles") is a valid XPath. but since I don’t know your XSL file, I can’t tell you what the XPath should be, because that depends on how you call it.

for instance
<xsl:template match="bookname">
<xsl:element name="whatever">
<xsl:attribute name="local-name()">
<xsl:value-of select="substring(./text(), 1, 1)"/>
</xsl:atribute>
</xsl:element>
</xsl:bookname>
would probably work

sorry for being new to this but could you explain local-name()?

Dormilich
04-19-2010, 11:13 AM
local-name(), local-name(nodeset): Returns the name of the current node or the first node in the specified node set - without the namespace prefix


i.e. in your case local-name() = "bookname"

TheJoey
04-19-2010, 11:29 AM
When testing it threw saxon, i got this error dorm.

XTSE0010: An xsl:template element must not contain an xsl:template element
XTSE0010: Element must be used only at top level of stylesheet


its not liking the <xsl:element> within template

Dormilich
04-19-2010, 12:01 PM
its not liking the <xsl:element> within template

the error states something different. it complaines about <xsl:template> inside <xsl:template>

TheJoey
04-19-2010, 12:10 PM
Ohh i can see this in my code

but how i can do it without multiple xsl:templates


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:template match ="booktype">
<xsl:element name="booktype"><xsl:attribute name="type"/></xsl:element>
</xsl:template>

<xsl:template match="bookname">
<xsl:element name="bookname">
<xsl:attribute name="bookname">
<xsl:value-of select="substring(./text(), 1, 1)"/>
</xsl:atribute>
</xsl:element>
</xsl:bookname>
</xsl:template>

</xsl:stylesheet>

Dormilich
04-19-2010, 12:44 PM
what about <xsl:apply-templates/>?

of course you can use multiple <xsl:template>, you just must not nest them.

PS. please fix the typo (or simply remove) <xsl:bookname>

TheJoey
04-19-2010, 02:19 PM
i have one apply template and its on its own

<xsl:apply-templates select="bookname" />

Dormilich
04-19-2010, 02:28 PM
you know that <xsl:apply-templates> is not a top-level element? besides, you didn’t post anything that contained it.

TheJoey
04-19-2010, 02:40 PM
Thank you, i seemed to have fixed that issue, thank you, its now pointing to markup issues which seem clear thank you again dorm

Dormilich
04-19-2010, 02:42 PM
FYI, top-level elements (http://www.w3.org/TR/xslt#stylesheet-element).