Reputation: 1759
This is my XML structure:
<bibliography>
<element>
<name>name</name>
<author><bold>author</bold></author>
<title>some <italic>title</italic></title>
<pages>123</pages>
</element>
...
</bibliography>
So I add commas with this template:
<xsl:template match="/*/*/*">
<xsl:if test="position()>2">, </xsl:if>
<xsl:value-of select="normalize-space()"/>
</xsl:template>
<xsl:strip-space elements="*" />
This works, BUT this ignores every element below /*/*/*
. Because of this every <bold>
and <italic>
tag will be ignored.
How can I fix this?
This is how I handle the <bold>
and <italic>
tags from my XML:
<xsl:template match="bold">
<span style="font-weight:bold;">
<xsl:apply-templates/>
</span>
</xsl:template>
<xsl:template match="italic">
<span style="font-style:italic;">
<xsl:apply-templates/>
</span>
</xsl:template>
Here is my full XML and XSLT, they might help findind the problem.
Upvotes: 0
Views: 3103
Reputation: 5256
UPDATE (Finally solved it :) )
Basically Following changes from the original xsl :
<xsl:template match="bibliography/*/*" priority="0">
<xsl:if test="position()>2">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
Added :
<xsl:strip-space elements="*" />
<xsl:template match="text()">
<xsl:value-of select='normalize-space()'/>
</xsl:template>
This is the final code :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="bibliography">
<html>
<head>
<title>Bibliographie</title>
<style type="text/css">
.entry {
font-family: Georgia;
}
</style>
</head>
<body>
<table>
<tbody>
<xsl:apply-templates/>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="bibliography/*">
<tr>
<td align="left">[<xsl:number count="*"/>]</td>
<td align="left">
<xsl:apply-templates/>
</td>
</tr>
</xsl:template>
<xsl:template match="bibliography/*/*" priority="0">
<xsl:if test="position()>2">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="bold">
<span style="font-weight:bold;">
<xsl:apply-templates/>
</span>
</xsl:template>
<xsl:template match="italic">
<span style="font-style:italic;">
<xsl:apply-templates/>
</span>
</xsl:template>
<xsl:strip-space elements="*" />
<xsl:template match="text()">
<xsl:value-of select='normalize-space()'/>
</xsl:template>
<xsl:template match="name" priority="1"/>
</xsl:stylesheet>
And Output :
Previous Suggestions :
strip-space
Use <xsl:strip-space elements="*" />
, it will remove 1st ',' problem.
For trimming spaces refer : https://stackoverflow.com/a/13974534/3603806
You can also use : fn:normalize-space() for trim. Here's the link : http://www.w3schools.com/Xpath/xpath_functions.asp#string
And explanation :
fn:normalize-space(string)
fn:normalize-space()
Removes leading and trailing spaces from the specified string, and replaces all internal sequences of white space with one and returns the result. If there is no string argument it does the same on the current node
Example: normalize-space(' The XML ')
Result: 'The XML'
Change your code to :
<xsl:template match="/*/*/*">
<xsl:if test="position()>2">, </xsl:if>
<xsl:value-of select="normalize-space()"/>
</xsl:template>
This is the result :
Upvotes: 1
Reputation: 117102
Your basic mistake is that you are using xsl:value-of
instead of xsl:apply-templates
. It's also not clear to me why you're using an awkward and inefficient construct like:
<xsl:template match="/*/*/*">
instead of using explicit element names, for example:
<xsl:template match="element">
<xsl:apply-templates/>
</xsl:template>
then use specific templates to handle each descendant node - including bold
and italic
, for example:
<xsl:template match="author">
<xsl:apply-templates/>
<xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="bold">
<span style="font-weight:bold;">
<xsl:apply-templates/>
</span>
</xsl:template>
<xsl:template match="italic">
<span style="font-style:italic;">
<xsl:apply-templates/>
</span>
</xsl:template>
If you want to have a generic template for all children of element except author, you could use something like:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="element">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="element/*">
<xsl:apply-templates/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="author" priority="1">
<xsl:apply-templates/>
<xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="bold">
<span style="font-weight:bold;">
<xsl:apply-templates/>
</span>
</xsl:template>
<xsl:template match="italic">
<span style="font-style:italic;">
<xsl:apply-templates/>
</span>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1