Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

use variables in xsl ? 1

Status
Not open for further replies.

tyris

Programmer
Nov 2, 2000
311
FR
hi all,
i do have an xml document this way :

Code:
<document name=&quot;Marketing&quot;>
	<tables count=&quot;1&quot;>
		<table name=&quot;AllDocuments&quot;>
			<columnHeaders count=&quot;3&quot;>
			     <columnHeader text=&quot;Site&quot;/>
			     <columnHeader text=&quot;Status&quot;/>
			     <columnHeader text=&quot;Account&quot;/>
			</columnHeaders>
			<rows count=&quot;134&quot;>
				<row>
				      <column>Paris</column>
				      <column>Project Completed</column>
				      <column>Microsoft (France)</column>
				</row>
				<row>
				      <column>Paris</column>
				      <column>Project Completed</column>
				      <column>Lionbridge Nortel</column>

				</row>
			</rows>
		</table>
	</tables>
</document>

what i'd like is :
display each row &quot;talking&quot; about the Account. i thought i could make a <xsl:if test=&quot;columnHeaders='Account'&quot;> then give the number of the row (incremented at each columnHeaders i found)
and then for each <column> use a second variable incremented, test if this one is equal to the one for columnHeaders and if yes, display it.

i don't know how it could be done. is there a way :
1. to use variable and increment them
2. test them with and other variable Best regards X-),
Elise
 
Hello,
I would suggest that you redesign your xml.
See thread426-101326 for example how to assure relations between your data. Then you'll be able to do your task.
If you still have problems post again.
I'll try to provide example.

XSLT is not procedural language.
You can use <xsl:variable> in two ways - one is set a value, then only get value. You cannot do a loop in such way.
When getting a value of a variable you can test value of other variable also.

<xsl:variable name=&quot;bookCount&quot; select=&quot;count(//book)&quot;/>
<xsl:variable name=&quot;bookTotal&quot; select=&quot;sum(//book/price)&quot;/>
<xsl:variable name=&quot;bookAverage&quot; select=&quot;$bookTotal div $bookCount&quot;/>

<xsl:if test=&quot;(price - $bookAverage) > 15&quot;/>

D.
 
thanks, i have made some works, i'm now at this step :
i try to do this :

[declare a variable called x]

<!-- locate Product index and keep it in a variable -->
<xsl:template match=&quot;document/tables/table/columnHeaders/columnHeader&quot;>
<xsl:if test=&quot;@text[.='Project']&quot;>
[make x = position()]
</xsl:if>

</xsl:template>


<!-- make a comparison with each column index to know if it's a product-->
<xsl:template match=&quot;/&quot;>
<xsl:for-each select=&quot;document/tables/table/rows/row&quot;>
<xsl:for-each select=&quot;column&quot;>
[if position() = the x i have initialise before then display]

</xsl:for-each>
</xsl:for-each>

the problem is that it seems that in the last part (<xsl:template match=&quot;/&quot;>) x is unknown. what is the way to :
1. define a variable
2. give this variable a value in one template
3. red this value in an other template


the problem is that it seems that in the last part (<xsl:template match=&quot;/&quot;>) x is unknown. what is the way to :
1. define a variable
2. give this variable a value in one template
3. red this value in an other template

sorry for my english, i'm french Best regards X-),
Elise
 
Hello,
Variables serve as additional tool. They are local to place where they are defined. So you cannot do procedural tasks with them as with other programming languages.
There are other techniques <xsl:param>, <xsl:with:param>, <xsl:call-template> that provide ways to set values outside of a template, and use them inside.
I'll try to provide more info on them in my next message.

I assume that there will be other answers except mine, but let's try to show you simpler way of getting the task done.

I suppose that you can control how your xml file look.
I suggest that you use the following xml:

<document name=&quot;Marketing&quot;>
<tables count=&quot;1&quot;>
<table name=&quot;AllDocuments&quot;>
<columnHeaders count=&quot;3&quot;>
<columnHeader id=&quot;1&quot;>Site</columnHeader>
<columnHeader id=&quot;2&quot;>Status</columnHeader>
<columnHeader id=&quot;3&quot;>Account</columnHeader>
</columnHeaders>
<rows count=&quot;134&quot;>
<row>
<column id=&quot;1&quot;>Paris</column>
<column id=&quot;2&quot;>Project Completed</column>
<column id=&quot;3&quot;>Microsoft (France)</column>
</row>
<row>
<column id=&quot;1&quot;>Paris</column>
<column id=&quot;2&quot;>Project Completed</column>
<column id=&quot;3&quot;>Lionbridge Nortel</column>
</row>
</rows>
</table>
</tables>
</document>

In such way in each row you will have clear indication to which column header it belongs.

Then you could use one of the following templates to diplay a table with column headers and rows:

1) one template with &quot;for-each&quot; style
<xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot; <xsl:template match=&quot;/&quot;>
<html>
<body>
<table border=&quot;1&quot;>
<tr>
<th/>
<xsl:for-each select=&quot;//columnHeader&quot;>
<th>
<xsl:value-of select=&quot;.&quot;/>
</th>
</xsl:for-each>
</tr>
<xsl:for-each select=&quot;//row&quot;>
<tr>
<td>
<xsl:value-of select=&quot;position()&quot;/>
</td>
<xsl:for-each select=&quot;column&quot;>
<td>
<xsl:if test=&quot;@id = 2&quot;>
<xsl:attribute name=&quot;bgcolor&quot;>yellow</xsl:attribute>
</xsl:if>
<xsl:value-of select=&quot;.&quot;/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>


2) many templates without &quot;for-each&quot;

<xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot; <xsl:template match=&quot;/&quot;>
<html>
<body>
<table border=&quot;1&quot;>
<tr>
<th/>
<xsl:apply-templates select=&quot;//columnHeader&quot;/>
</tr>
<xsl:apply-templates select=&quot;//row&quot;/>
</table>
</body>
</html>
</xsl:template>

<xsl:template match=&quot;columnHeader&quot;>
<th>
<xsl:value-of select=&quot;.&quot;/>
</th>
</xsl:template>

<xsl:template match=&quot;row&quot;>
<tr>
<td>
<xsl:value-of select=&quot;position()&quot;/>
</td>
<xsl:apply-templates select=&quot;column&quot;/>
</tr>
</xsl:template>

<xsl:template match=&quot;column&quot;>
<td>
<xsl:choose>
<xsl:when test=&quot;@id = 2&quot;>
<font color=&quot;red&quot;>
<xsl:value-of select=&quot;.&quot;/>
</font>
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select=&quot;.&quot;/>
</xsl:eek:therwise>
</xsl:choose>
</td>
</xsl:template>

</xsl:stylesheet>

3) Even more templates without &quot;for-each&quot;, without if
<xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot; <xsl:template match=&quot;/&quot;>
<html>
<body>
<table border=&quot;1&quot;>
<tr>
<th/>
<xsl:apply-templates select=&quot;//columnHeader&quot;/>
</tr>
<xsl:apply-templates select=&quot;//row&quot;/>
</table>
</body>
</html>
</xsl:template>

<xsl:template match=&quot;columnHeader&quot;>
<th>
<xsl:value-of select=&quot;.&quot;/>
</th>
</xsl:template>

<xsl:template match=&quot;row&quot;>
<tr>
<td>
<xsl:value-of select=&quot;position()&quot;/>
</td>
<xsl:apply-templates select=&quot;column&quot;/>
</tr>
</xsl:template>

<xsl:template match=&quot;column&quot;>
<td>
<xsl:value-of select=&quot;.&quot;/>
</td>
</xsl:template>

<xsl:template match=&quot;column[@id=2]&quot;>
<td>
<xsl:attribute name=&quot;bgcolor&quot;>yellow</xsl:attribute>
<xsl:value-of select=&quot;.&quot;/>
</td>
</xsl:template>

</xsl:stylesheet>

Wish you success!
I'll try to post more info on other ways also.
D.
 
great, i think you gave me many possibilities, i thong i can do something good now thanks Best regards X-),
Elise
 
great, i think you gave me many possibilities, i think i can do something good now thanks Best regards X-),
Elise
 
I'm trying to dynamically set the url for the action parameter in a form tag using xsl stylesheets to process genrated xml output from my application to produce html that is sent to the client.

I have a database servlet that I'd like to run on different servers, but I'd like not to have to rewrite all the form tags in the xsl files that process the xml to generate the html.

I've tried to use xsl:element to build the form tag with the url coming in as a <server_url> . . </server_url> xml tag. However, SAX chokes on this and seems to think there is not a terminator for an xsl:template tag, which is not the case. I've also tried it with a variable, but run into problems with the parser because of special characters.

Suggestions?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top