is this stylesheet valid?

A

Andy Fish

hi,

i'm porting some xsl code from .net 1.1 to 2.0 and I have come across a
transform which works in .net 1.1 and works in mxsml but does not work in
..net 2.0. the stylesheet is this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="foo">
<xsl:param name="param1"/>
<xsl:value-of select="$param1/*"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

and the input file is simply

<foo />

so $param1 has no value (empty string? empty node set? I'm not sure)

with .net 2.0 I get an error message Unhandled Exception:
System.Xml.XPath.XPathException: Expression must evaluate to a node-set. I'm
guessing this is because the default parameter value is an empty string.

in the real stylesheet, the parameter (if it is passed in) will be a node
set. so to make sure I don't evaluate an illegal expression, I need to be
able to tell whether the parameter value is an empty string (i.e. default)
or a node set. how can I achieve this?

Andy
 
J

Joe Kesselman

(I can't reply to the Microsoft group -- despite the ".public." in its
name it doesn't accept posts -- so I hope you're watching c.t.xml.)


Andy said:
<xsl:value-of select="$param1/*"/>
so $param1 has no value (empty string? empty node set? I'm not sure)

with .net 2.0 I get an error message Unhandled Exception:
System.Xml.XPath.XPathException: Expression must evaluate to a node-set.

You can't ask for the children of a string.

You can ask for the children of an empty nodeset; that always comes back
as empty.
I need to be
able to tell whether the parameter value is an empty string (i.e. default)
or a node set. how can I achieve this?

That's an Interesting Question. XSLT 2.0 has a test for the type of a
value, but I'm not sure how to express that in 1.0. Let me think about
that a bit.

An alternative would be to reverse the problem. Modify your xsl:param to
specify what the default value is -- either make it explicitly an empty
nodeset value, or make the default some explicit value and test for that.
 
J

Joseph Kesselman

http://www.exslt.org/exsl/functions/object-type/

Good solution if your processor supports the EXSLT extension functions,
and many do these days so it's _almost_ reliably portable. <smile/>

(In many ways, EXSLT was an experimental base for ideas that found their
way into XSLT 2.0, so it's definitely worth checking there if you need a
feature that 2.0 has but 1.0 doesn't. I should review that collection
myself.)
 
I

Ixa

Good solution if your processor supports the EXSLT extension functions,
and many do these days so it's _almost_ reliably portable. <smile/>

As always, reader's discretion is advised. :)

I guess EXSLT suits for this particular case as it is (AFAIK) available
on .NET. XSLT2 would be even better, but IIRC the native support is
still on its way.
 
D

David Carlisle

Andy said:
hi,

i'm porting some xsl code from .net 1.1 to 2.0 and I have come across a
transform which works in .net 1.1 and works in mxsml but does not work in
.net 2.0. the stylesheet is this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="foo">
<xsl:param name="param1"/>
<xsl:value-of select="$param1/*"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

and the input file is simply

<foo />

so $param1 has no value (empty string? empty node set? I'm not sure)

with .net 2.0 I get an error message Unhandled Exception:
System.Xml.XPath.XPathException: Expression must evaluate to a node-set. I'm
guessing this is because the default parameter value is an empty string.

in the real stylesheet, the parameter (if it is passed in) will be a node
set. so to make sure I don't evaluate an illegal expression, I need to be
able to tell whether the parameter value is an empty string (i.e. default)
or a node set. how can I achieve this?

Andy


rather than have it default to an empty string, and then having to test
for that to avoid using the variable in path expressions, it's usually
simpler just to make it default to an empty node set, add
<xsl:param name="param1" select="/.."/>

David
 
A

Andy Fish

David Carlisle said:
rather than have it default to an empty string, and then having to test
for that to avoid using the variable in path expressions, it's usually
simpler just to make it default to an empty node set, add
<xsl:param name="param1" select="/.."/>

David

Thanks david, that's pretty much what I ended up doing

unfortunately there were quite a lot of templates with this optional
parameter, although only one of them actually used the parameter. they are
calling each other like this:

<xsl:template match="...">
<xsl:param name="param1"/>
....
<xsl:apply-templates>
<xsl: with-param name="param1" select="$param1"> </xsl:template>
</xsl:apply-templates/>
</xsl:template >

now, if any one of them gets called without a parameter, it passes in the
blank parameter into the ones it calls (rather than not passing in a
parameter - hence the default value does not apply), so this meant I had to
put the default parameter into every one of the templates, not just the one
that needed it.

so as well as some way of telling whether a variable contains a node set,
string or RTF, I would also like to have an option on <xsl:call-template>
and <xsl:apply template> that said:

if this parameter was passed in to me, pass the parameter into the next
template,. otherwise don't pass in the parameter into the next template

Andy
 
P

Pavel Lepin

Andy Fish said:
unfortunately there were quite a lot of templates with
this optional parameter, although only one of them
actually used the parameter.

[...]
so as well as some way of telling whether a variable
contains a node set, string or RTF, I would also like to
have an option on <xsl:call-template> and <xsl:apply
template> that said:

if this parameter was passed in to me, pass the parameter
into the next template,. otherwise don't pass in the
parameter into the next template

Read XSLT2 spec, 10.1.2 and rejoice. (Although I must say I
don't see how precisely that would help you, since from the
description of your predicament it would seem you'd have to
specify the tunneling everywhere anyway.)
 

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

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top