Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
| FAQ | Members List | Search | Today's Posts | Mark Forums Read
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 tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old April 24th, 2007, 05:20 PM
Authorized User
 
Join Date: Apr 2007
Location: , , .
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default node-set() -- moving from msxsl to saxon, etc.

My xslt currently uses msxsl:node-set(). This works fine when transforming xml via msxsl from the command line and also previewing it in IE7. However, msxsl:node-set() is not recognized by saxon or Firefox, so I cannot use those with my xml and xslt.

Since Vista's IE7 is having trouble w/ xslt, I'd like to preview in Firefox. While I'm at it, I would like to see if I can use Saxon instead of msxsl.

What are the recommended steps for migrating away from msxsl:node-set()?

Thanks!

Travis

Reply With Quote
  #2 (permalink)  
Old April 24th, 2007, 06:20 PM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

With XSLT 2.0, the need for the node-set extension disappears entirely. So if you can wean yourself off client-side transformation, you might as well move to XSLT 2.0 and get all the other benefits as well. There are two main processors available: Saxon and Altova. Saxon of course is by far the best ;)

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #3 (permalink)  
Old April 24th, 2007, 06:26 PM
Friend of Wrox
Points: 1,676, Level: 16
Points: 1,676, Level: 16 Points: 1,676, Level: 16 Points: 1,676, Level: 16
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jul 2006
Location: , , .
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
Send a message via Yahoo to bonekrusher
Default

I use both. I will have to say that SAXON out performs Altova by a a long shot. For example; I have a file that list about 870 xml file. My xslt calls each with the document function. SAXON usually runs in seconds, where Altova's takes tens of minutes...

SAXON is by far the best.

Reply With Quote
  #4 (permalink)  
Old April 24th, 2007, 10:05 PM
Authorized User
 
Join Date: Apr 2007
Location: , , .
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I like Saxon's error messages a lot more than msxsl's, and would prefer to use Saxon for static xhtml generation.

However, I also like to preview my xslt-powered pages in a browser before running the xslt. Up until now I've been using IE7 for all the previewing (since Firefox doesn't understand msxsl:node-set()).

Do you know if Firefox supports XSLT 2.0 enough to allow me to skip the node-set()? Or is Firefox's XSLT support still limited to XSLT 1.x? (I suspect the latter)

I'd like to baby-step towards XSLT 2.0. To do that, I would like to first try to isolate the msxsl:node-set() usage. Right now my xslt has 10 occurances of msxsl:node-set(). I'd like to put the msxsl:node-set() call in a named template, and then change all 10 references to "call" that template like a function. Does this sound like a decent plan, or am I thinking too much like a conventional programmer? I haven't done any refactoring of my xslt in years and am worried that I'm going to mess things up...

Is there a guide for isolating node-set() usage? I vaguely remember reading something about it years ago but have no idea which keywords to google.

Thanks!

Reply With Quote
  #5 (permalink)  
Old April 24th, 2007, 10:22 PM
Authorized User
 
Join Date: Apr 2007
Location: , , .
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Here's an example of how I am using msxsl:node-set():
Code:
<xsl:variable name="html">
  <html>
    <head>...</head>
    <body><xsl:apply-templates select="blaa" />...</body>
  </html>
</xsl:variable>
<xsl:apply-templates mode="indent" select="msxsl:node-set($html)" />
In this instance, I'm assigning my html output (which is dynamically constructed via xslt) to a variable, which I then pass to my "indent" template (which cleans up the indentation). I use node-set() so that I can treat the html like a tree of nodes rather than a string.

I'm not sure how I can move the msxsl:node-set() reference away from this code. I can't just pass $html to some other template which calls msxsl:node-set() on it, can I?

Ideas?
Reply With Quote
  #6 (permalink)  
Old April 25th, 2007, 01:59 AM
joefawcett's Avatar
Wrox Author
Points: 9,763, Level: 42
Points: 9,763, Level: 42 Points: 9,763, Level: 42 Points: 9,763, Level: 42
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Exeter, , United Kingdom.
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

One possibility it to embed the data in the stylesheet and use the document() function. There is also a problem with that though, not all browsers support it.
Code:
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:myData="http://joe.fawcett.name/xslt/examples"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl myData">
  <xsl:variable name="useVariable">
    <variable/>
  </xsl:variable>
  <myData:useEmbedded>
    <embedded/>
  </myData:useEmbedded>

  <xsl:template match="/">
    <example>
      <xsl:copy-of select="msxsl:node-set($useVariable)/variable"/>
      <xsl:copy-of select="document('')/*/myData:useEmbedded/embedded"/>
    </example>  
  </xsl:template>
</xsl:stylesheet>
You can run the above with any dummy input XML.

--

Joe (Microsoft MVP - XML)
Reply With Quote
  #7 (permalink)  
Old April 25th, 2007, 09:03 AM
Authorized User
 
Join Date: Apr 2007
Location: , , .
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Joe - Thanks! I tried your example (and modified it a bit). When my data contains xsl:* elements, those elements get copied to the output too. So, document('') appears to treat all contents of the selected elements literally. This would work if "embedded" contains data only, but if it contains xsl:value-of, xsl:apply-templates, etc., it doesn't work.

So, this works:
Code:
<myData:useEmbedded>
  <embedded>
    <p>hi there</p>
    <p>this is just data</p>
  </embedded>
</myData:useEmbedded>
But this doesn't (the xsl:value-of gets copied to the output):
Code:
<myData:useEmbedded>
  <embedded>
    <p>hi there</p>
    <p><xsl:value-of select="'this is xsl markup'" /></p>
  </embedded>
</myData:useEmbedded>
This sort of makes sense since document('') tries to treat xslt markup as xml data. Is this the main weakness of the document('') strategy?

NOTE: I updated my earlier example (changes in red) to emphasize that my "html" element is dynamically constructed via xslt (instead of consisting of data only).
Reply With Quote
  #8 (permalink)  
Old April 25th, 2007, 09:20 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Yes, document('') only works for fixed XML fragments.

If you want to construct an XML tree and then process it as XML in the same stylesheet, then you're basically hosed: you either need the node-set() extension, or an XSLT 2.0 processor, or a processor that implements XSLT 1.0 but lifts this restriction in the spec (I think there are one or two but don't recall the detail).

You do sometimes find the node-set() extension used where it isn't needed, inserted by people who haven't fully understood what it's for. In that case you can just replace xx:node-set($x) by $x.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #9 (permalink)  
Old April 25th, 2007, 09:40 AM
Authorized User
 
Join Date: Apr 2007
Location: , , .
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks, Michael!

It looks like Firefox doesn't support XSLT 2.0 or a node-set() function yet. The next version of Firefox (3.0) is supposed to support exsl:node-set(), which is better than nothing, but that's probably a couple months away.

If Firefox 3.0 supports esxl:node-set() and IE7 supports msxsl:node-set() and Saxon supports XSLT 2.0, then it would be nice to isolate those differences in a single file or template. I'd love to have a single chunk of xslt detect which engine is running and then select the appropriate node-set logic. However, I realize that's a "conventional" programming tactic which might not work with xslt.

Out of curiosity, how do you preview your XSLT output? Do you use IE7 or Firefox or some other XSLT rendering tool? Or do you always use Saxon to generate static output, and then open the static output in a browser?


Reply With Quote
  #10 (permalink)  
Old April 25th, 2007, 10:08 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

XSLT allows you to write code like this:

<xsl:when test="system-property('xsl:vendor')='Microsoft')">
  <xsl:value-of select="msxml:node-set($x)"/>
</xsl:when>
<xsl:when test="system-property('xsl:vendor')='Mozilla')">
  <xsl:value-of select="moz:node-set($x)"/>
</xsl:when>

etc. (You'll have to check the actual vendor names)

I usually do XSLT development work either (a) using Saxon and UltraEdit and the command line, or (b) using Saxon within Stylus Studio. If it has to run in the browser I only test in the browser once it's working elsewhere. That's because the browser environment is pretty bad for diagnostics.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
XPath: set operation with a disjoint node set rich_unger XSLT 7 May 6th, 2008 09:24 AM
Expression must evaluate to a node-set. XMLUser XSLT 3 February 5th, 2008 01:27 PM
Converting String into Node-set dved XSLT 3 January 23rd, 2008 12:40 PM
Filtering out from a node set anothervbaddict XSLT 1 May 22nd, 2007 08:42 AM
node-set function Bernardo Pacheco XSLT 2 June 19th, 2006 10:45 AM



All times are GMT -4. The time now is 07:50 PM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.