param in for-each select statement doesnt seem to work

X

xmlhelp

stuff.XSL:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="uid"/>
<xsl:template match="/">
parameter UID=<xsl:value-of select="$uid"/>
<table border="1">
<tr>
<xsl:for-each select="row[data[3]/value=20]">
<td>
<xsl:value-of select="data[1]/value"/>
<xsl:value-of select="data[2]/value"/>
</td>
</xsl:for-each>
</tr></table>
</xsl:template></xsl:stylesheet>

stuff.XML:
<row>
<data>
<value>NAME</value>
</data>
<data>
<value>DATA</value>
</data>
<data>
<value>20</value>
</data>

stuff.asp:
<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<!--#include
file="includes/MM_XSLTransform/MM_XSLTransform.classVB.asp"
--><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"
/>
<title>XML</title>
</head>

<body>
<%
Dim mm_xsl: Set mm_xsl = new MM_XSLTransform
mm_xsl.setXML "stuff.xml"
mm_xsl.setXSL "stuff.xsl"
mm_xsl.addParameter "uid", request.QueryString("uid")
Response.write mm_xsl.Transform()
%>
</body>
</html>

=========

theres obviously lots of records and this is simplified to just display
the jist of what i'm doing... which is trying to pull out all the row
elements from the XML file where the 3rd data element's value in a row
element is 20

if i call the page on an asp file with stuff.asp?uid=20
then:
parameter UID=<xsl:value-of select="$uid"/>
will output "parameter UID=20"

if i change:
<xsl:for-each select="row[data[3]/value=20]">
to
<xsl:for-each select="row[data[3]/value=$uid]">
then i get nothing returned from the for-each. with the hardcoded 20
though, it will output what it is supposed to. i assume my syntax for
including the param in the for-each wrong, but i can't figure out how
to fix it...
 
P

p.lepin

xmlhelp said:
stuff.XSL:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="uid"/>
<xsl:template match="/">
parameter UID=<xsl:value-of select="$uid"/>
<table border="1">
<tr>
<xsl:for-each select="row[data[3]/value=20]">

for-each! Renounce your evil ways! Use templates!

Seriously, for-each *is* evil. For one thing, its name is
misleading. It's really just an inline template together
with the template application.

<xsl:for-each select="...">
foo
</xsl:for-each>

....is virtually the same as:

<xsl:apply-templates select="..."
mode="absolutely-unique-mode"/>
....
<xsl:template match="..." mode="absolutely-unique-mode">
foo
</xsl:template>

....the difference being that the real template is readily
reusable. And for-each is not. And for-each gives XSLT
neophytes the illusion that they're still doing good ole
imperative programming. Evil.
<td>
<xsl:value-of select="data[1]/value"/>
<xsl:value-of select="data[2]/value"/>
</td>
</xsl:for-each>
</tr></table>
</xsl:template></xsl:stylesheet>

The output is not well-formed. Either use <output
method="text"/> or make sure your transformation outputs
actual XML.
stuff.XML:
<row>
<data>
<value>NAME</value>
</data>
<data>
<value>DATA</value>
</data>
<data>
<value>20</value>
</data>

It's not well-formed. If you want help, you'd better post
something that makes it easier for people to help you.
stuff.asp:
[ASP]

theres obviously lots of records and this is simplified
to just display the jist of what i'm doing... which is
trying to pull out all the row elements from the XML file
where the 3rd data element's value in a row element is 20
[...]

if i change:
<xsl:for-each select="row[data[3]/value=20]">
to
<xsl:for-each select="row[data[3]/value=$uid]">
then i get nothing returned from the for-each. with the
hardcoded 20 though, it will output what it is supposed
to. i assume my syntax for including the param in the
for-each wrong, but i can't figure out how to fix it...

Works nicely for me (libxslt/PHP5 XSL module). I'd
recommend asking for help on Microsoft's newsgroups, this
is probably related to something in MSXML/ASP, not in XSLT.
Just fix your XML & XSLT before posting there.
 
R

Richard Tobin

[...]

You stylesheet looks ok, but I don't know anything about ASP.
Assuming that the parameter gets passed in as a string, there will
be a small difference: when you have the 20 hard-coded, it's a number,
but in the parameter version it will be a string, so the comparison
will be a string comparison instead of a numeric one. Are you sure
there are no spaces around either the data in the XML file or the
parameter value you are setting? That would cause the string
comparison to fail.

-- Richard
 
R

Richard Tobin

for-each! Renounce your evil ways! Use templates!
Nonsense.

Seriously, for-each *is* evil. For one thing, its name is
misleading. It's really just an inline template together
with the template application.

Why is "for-each" a misleading name for that?
...the difference being that the real template is readily
reusable. And for-each is not.
True.

And for-each gives XSLT
neophytes the illusion that they're still doing good ole
imperative programming. Evil.

Why is that evil?
The output is not well-formed. Either use <output
method="text"/> or make sure your transformation outputs
actual XML.

The output with the XML output method is not required to be a well-formed
XML document, only a well-formed XML external parsed entity. So a mixture
of elements and text is perfectly legal.

-- Richard
 
P

p.lepin

Richard said:
Why is "for-each" a misleading name for that?

I suppose because in a number of modern popular languages
(for some values of 'modern' and 'popular') foreach refers
to a language construct describing iteration over an array
or a list. XSLT doesn't have arrays or lists and doesn't
really iterate. I find that misleading, and neophytes
talking about the 'for loops' on the group seem to support
my point, but YMMV.
Why is that evil?

It's evil -- in my opinion -- because the longer they delay
the transition to declarative mindset, the harder it seems
to become.

Overall, my 'for-each considered harmful' rants are only
about half-serious, and I'm sorry if that's not obvious
from reading them. I still believe it's a good advice to
drop them unless you have a very good reason not too, but
I'm not waging a holy war on blasphemous for-each-users,
not really.
The output with the XML output method is not required to
be a well-formed XML document, only a well-formed XML
external parsed entity. So a mixture of elements and
text is perfectly legal.

My bad. It's the fault of my homegrown toolkit for
experimenting with XSLT -- it expects well-formed XML
documents out of transformations with <output
method="xml"/>. I'd still say it would be a good practice
to post stylesheets producing well-formed documents -- if
at all possible -- when posting examples to a newsgroup.
 
M

Magnus Henriksson

Overall, my 'for-each considered harmful' rants are only
about half-serious, and I'm sorry if that's not obvious
from reading them. I still believe it's a good advice to
drop them unless you have a very good reason not too, but
I'm not waging a holy war on blasphemous for-each-users,
not really.

Like any rule, you may break it if you have good reasons and if you are
aware that you are breaking it.

There are situations where for-each is useful...

// Magnus
 
J

Joe Kesselman

Seriously, for-each *is* evil.

Overstated somewhat, as I'm sure you'll admit. There are times when
for-each is the clearest way to express something, especially when
context variables are involved in the solution.

The only real problem is that for-each is an "attractive nuisance"
(legal term used to describe things like swimming pools which may
present a danger to kids who haven't learned not to trespass or how to
use them safely). It draws the attention of newbies, encouraging them to
write imperative solutions... which are generally harder to code, harder
to maintain, and generally uglier than the functional (or at least
modular!) approaches.
 
X

xmlhelp

thanks so much!

changed:
<xsl:for-each select="row[data[3]/value=$uid]">
to:
<xsl:for-each select="row[data[3]/value=number($uid)]">

and it works! i knew it had to be something rather simple.
interesting little debate over templates and for-each though here ;)
 
P

p.lepin

Joe said:
Overstated somewhat, as I'm sure you'll admit.

More than that, intentionally overstated. I hoped it would
be easier to swallow that way, but obviously people
thought I was seriously religious about that.
There are times when for-each is the clearest way to
express something, especially when context variables are
involved in the solution.

Can't argue with that.
The only real problem is that for-each is an "attractive
nuisance" (legal term used to describe things like
swimming pools which may present a danger to kids who
haven't learned not to trespass or how to use them
safely). It draws the attention of newbies, encouraging
them to write imperative solutions... which are generally
harder to code, harder to maintain, and generally uglier
than the functional (or at least modular!) approaches.

I suppose,
considered(X,harfmul) :- attractive(X), nuisance(X).

| ?- considered(X,harmful).

X = goto ? ;

X = xslforeach ? ;

X = swimmingpool ? ;

X = mywife

yes
 
J

Joseph Kesselman

More than that, intentionally overstated. I hoped it would
be easier to swallow that way, but obviously people
thought I was seriously religious about that.

Irony doesn't work very well in newsgroups; it's often hard to tell
whether folks are serious or not. (I often find that frustrating since
my own sense of humor leans strongly in that direction.)
 

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

Staff online

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top