Reputation: 422
Here is my xml example :
(it's a example from w3school reformatted for my case)
my xsl try:
<?xml version="1.0" encoding="US-ASCII" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" omit-xml-declaration="no" indent="yes" />
<xsl:template match="/">
<xsl:call-template name="loop">
<xsl:with-param name="var">3</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="loop">
<xsl:param name="var"></xsl:param>
<xsl:choose>
<xsl:when test="$var > 0">
<table border="1">
<tr bgcolor="#9acd32">
<th>Index</th>
<th>TestText</th>
</tr>
<td><xsl:value-of select="number($var)"/></td>
<xsl:variable name="titleVar" select="concat('catalog/title',string(number($var)))" />
<td><xsl:value-of select="*[$titleVar]"/></td>
<!--<td><xsl:text>I am in a loop </xsl:text></td>-->
<xsl:call-template name="loop">
<xsl:with-param name="var">
<xsl:number value="number($var)-1" />
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:text>I am out of the loop</xsl:text>
</xsl:otherwise>
</table>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
and I am trying to loop trough and getting just title but I dont get the specific attribute... I get all the catalog :-/
If anyone can help me ? Thx
Upvotes: 0
Views: 148
Reputation: 1103
Your stylesheet is not well formed. You must close <table>
inside <xsl:when>
.
Also, your template call doesn't make much sense. Note, that xsl:call-template
does not change your current node. Your current node will remain the document node (which is not <catalog>
but the entire document). So in your case, <xsl:template match="/">
matches your document node and then calls the template <xsl:template name="loop">
, which recurs 3 times because of your param var
. Note, that <xsl:apply-templates>
also loops on any sequence you define in the select
attribute. So if you want to loop through something, most of the time, apply-templates
is a better choice.
The reason why you get all the catalogs text nodes (you actually don't get all the catalog), is because of the following line: <td><xsl:value-of select="*[$titleVar]"/></td>
<xsl:value-of>
returns the value of the selected nodes as text. In your case this means all text nodes in your document. This is because the context in which your called template loops and because $titleVar
returns a string, so your predicate (['catalog/title3']
) is of no use.
If you want the match a certain text node inside your document and the context remains the document node, you could use a pattern like <xsl:value-of select="descendant::node()[parent::title3]"/>
. Note, that text nodes are no element nodes, so instead of *
, you must use node()
.
Edit:
If you would like to process every node, which name starts with 'title', you would use apply-templates like this (and these are xslt basics):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<titles>
<!-- select a sequence of all child nodes of your
root element and search for matching templates-->
<xsl:apply-templates select="catalog/*"/>
</titles>
</xsl:template>
<!-- match every node, which starts with 'title'-->
<xsl:template match="*[starts-with(name(), 'title')]">
<title>
<xsl:value-of select="."/>
</title>
</xsl:template>
<!--match every node, but since the first template is more specific,
elements starting with 'title' will not be processed-->
<xsl:template match="*"/>
</xsl:stylesheet>
Upvotes: 1