 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

April 6th, 2010, 05:01 AM
|
|
Authorized User
|
|
Join Date: Mar 2010
Posts: 18
Thanks: 3
Thanked 0 Times in 0 Posts
|
|
Saxon 9HE and xquery for loops
Hi,
according to http://saxon.sourceforge.net/#F9.2HE saxon home edition supports the XQuery 1.0 final spec; but I can't get the following to work:
Code:
<xsl:for-each select="for $x in ('a','b','c') where 1=1 return $x">
<xsl:message select="."/>
</xsl:for-each>
If I try to compile that snippet I get:
Code:
Error at xsl:for-each on line 28 column 74 of testing.xsl:
XPST0003: XPath syntax error at char 24 on line 28 in {for $x in ('a','b','c') where ...}:
expected "return", found "null"
Failed to compile stylesheet. 1 error detected.
Is there something wrong with my xquery expression (I am look at this since an hour or so but can't figure it out, might be missing something obvious)?
Thanks in advance,
Florian
|
|

April 6th, 2010, 05:12 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Saxon supports either XSLT or XQuery but not both at once! The expressions used in the select attribute of an XSLT instruction must always be XPath expressions, not XQuery expressions. (Saxon would have no difficulty supporting what you attempted, but it's not permitted by the W3C specifications.)
In fact Saxon does allow XSLT and XQuery to be mixed, but only by cross-language function calling. There's a declaration saxon:import-query that allows you to import an XQuery function library into an XSLT stylesheet, after which you can call the functions in that module as if they had been written in XSLT.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|
The Following User Says Thank You to mhkay For This Useful Post:
|
|
|

April 6th, 2010, 05:24 AM
|
|
Authorized User
|
|
Join Date: Mar 2010
Posts: 18
Thanks: 3
Thanked 0 Times in 0 Posts
|
|
Ah thx. saxon:import-query is PE onwards only right? I solved that problem now by using an xsl:if inside the for-loop, but I guess it would be nicer to use the professional edition. On the other hand; I do hate license files… keeping track of 100++ license files is something I don't want to do either ;)
Thx again,
Florian
|
|

April 6th, 2010, 05:29 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
If you can solve the problem using an xsl:if inside the for loop, then you can probably solve it with a simple predicate:
<xsl:for-each select="expr[condition]">
....
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

April 6th, 2010, 05:48 AM
|
|
Authorized User
|
|
Join Date: Mar 2010
Posts: 18
Thanks: 3
Thanked 0 Times in 0 Posts
|
|
Hi,
yeah I did try that, but my xslt/xpath knowledge isn't good enough. That does work:
Code:
<xsl:for-each select="('fontcolor','fontsize','c')">
<xsl:if test="$table/col/@*[local-name() = current()]">
<xsl:attribute name="{.}" select="$table/col/@*[local-name() = current()]"/>
</xsl:if>
</xsl:for-each>
but I am not able to move that up into the for-each select attribute.
Florian
|
|

April 6th, 2010, 06:05 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
You have not described exactly what you want to achieve but I think that for-each you posted can simply be replaced by
Code:
<xsl:copy-of select="$table/col/(@fontcolor, @fontsize, @c)"/>
as it seems you simply want to copy those three attributes.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

April 6th, 2010, 06:13 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
I think Martin's solution works for this example.
More generally, you're doing a join here, and joins can be a bit tricky with XPath alone, but it can generally be done. If your attribute names weren't constant, for example, you could do
Code:
<xsl:for-each select="$name[some $a in $table/col/@* satisfies local-name($a) eq .]">
or more simply, exploiting the semantics of "=" when comparing sequences,
Code:
<xsl:for-each select="$name[. = $table/col/@*/local-name()]">
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

April 6th, 2010, 07:02 AM
|
|
Authorized User
|
|
Join Date: Mar 2010
Posts: 18
Thanks: 3
Thanked 0 Times in 0 Posts
|
|
Quote:
Originally Posted by Martin Honnen
You have not described exactly what you want to achieve but I think that for-each you posted can simply be replaced by
Code:
<xsl:copy-of select="$table/col/(@fontcolor, @fontsize, @c)"/>
as it seems you simply want to copy those three attributes.
|
Well I don't want to copy them (at least only to some extend), I want to take those three values out of the xml data [in this example simplified as $table] and, if defined, put them as attribute on fo:block [missing in my example]. So essentially I want to copy some attributes from the data source onto attributes of the output (xsl:fo in this case, later to be processed via apache fop).
Quote:
Originally Posted by mhkay
or more simply, exploiting the semantics of "=" when comparing sequences,
Code:
<xsl:for-each select="$name[. = $table/col/@*/local-name()]">
|
That one is really nice, and exactly what I need in thise caseâ¦
Thanks to both of you,
Florian
|
|
 |