Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
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
 
Old April 25th, 2007, 10:39 AM
Authorized User
 
Join Date: Apr 2007
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

BTW, I use UltraEdit too! Great app. :)

Is there a way to push the system-property switch into a single template, and then "call" that template in each case where I need an RTF fragment to be turned into a node set? Or does that not help because the template cannot "return" a node set?

For example, let's say we have:
Code:
<xsl:variable name="x">
  <books>
    <book author="Ann" year="1995" title="Zoos" />
    <book author="Bob" year="1991" title="Yaks" />
    <book author="Cal" year="1994" title="Xeroxes" />
    <xsl:apply-templates mode="getMoreBooks" />
  </books>
</xsl:variable>
<xsl:apply-templates mode="byAuthor" select="msxml:node-set($x)" />
...
<xsl:apply-templates mode="byTitle" select="msxml:node-set($x)" />
...
<xsl:apply-templates mode="byDate" select="msxml:node-set($x)" />
Would I have to have the system-property() switches three times (assuming we don't want to repeat the "..." bits for each parser? Or is there a way to move the system-property switch to a single location?
 
Old April 25th, 2007, 10:45 AM
Authorized User
 
Join Date: Apr 2007
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I'm guessing this doesn't work:
Code:
<xsl:variable name="y">
  <xsl:choose>
    <xsl:when test="system-property('xsl:vendor')='Microsoft')">msxml</when>
    <xsl:when test="system-property('xsl:vendor')='Mozilla')">moz</when>
  </xsl:choose>
</xsl:variable>
...
<xsl:apply-templates mode="byAuthor" select="$y:node-set($x)" />
...
<xsl:apply-templates mode="byTitle" select="$y:node-set($x)" />
...
<xsl:apply-templates mode="byDate" select="$y:node-set($x)" />
 
Old April 25th, 2007, 11:30 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>Or does that not help because the template cannot "return" a node set?

Spot on. Templates in XSLT 1.0 cannot return existing nodes, they can only create new nodes. This changes in 2.0.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old April 25th, 2007, 11:34 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

<xsl:apply-templates mode="byAuthor" select="$y:node-set($x)" /> ..

If we could construct the names of the functions we want to call dynamically, a lot of problems would go away... You're trying to turn XSLT into a real functional programming language. See the FXSL project.


Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old April 25th, 2007, 12:01 PM
Authorized User
 
Join Date: Apr 2007
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks. So, I'm guessing that if I want to retain "vanilla" XSLT 1.0 compatibility (though the reasons for doing so are diminishing since Vista IE7's XSLT rendering is buggy), then I will need to:

1) try to eliminate msxsl:node-set() references wherever possible

2) for the ones I cannot remove, add the system-property switch

3) wean myself off of browser-based previewing

?


 
Old April 26th, 2007, 03:05 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Quote:
quote:Originally posted by mhkay
 <xsl:apply-templates mode="byAuthor" select="$y:node-set($x)" /> ..

If we could construct the names of the functions we want to call dynamically, a lot of problems would go away... You're trying to turn XSLT into a real functional programming language. See the FXSL project.


Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
If the functions were all called node-set then what you'd need to do was dynamically assign the namespace to prefix mapping, the call can always be "ns:node-set(...)" just which namespace URI is associated with "ns". However, I don't think you can do that.

--

Joe (Microsoft MVP - XML)
 
Old April 26th, 2007, 08:14 AM
Authorized User
 
Join Date: Apr 2007
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Has anyone tried to implement an xslt parser/interpreter in xslt? It'd probably be mega-slow, but would let people [attempt to] extend the language without affecting portability.

 
Old May 1st, 2007, 06:35 PM
Authorized User
 
Join Date: Apr 2007
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I have managed to get rid of most of my node-set() occurances. However, I'm a bit stumped by one of the remaining ones.

I'm working on an album page. The album's XML lists songs by name. Each song has its data (length, lyrics, description) defined in an XML file whose name matches the song title. The XSLT for the album page does the following:

1) reads each song's data from its own XML file via document()
2) stores all songs' data in $songs variable using node-set()
3) references $songs in many locations

For example, in one place I add up the lengths of all the songs to get the album length. In another place, I add up the number of mp3s that the album has (based on each song's mp3 info). In another place, I list the songs in order next to each song's time, and links to the song's mp3 and lyrics. In another place, I have a long section for each song where I describe the song and display the lyrics. And so on. The page refers to $songs many times.

$songs is currently dependent upon node-set(). I did that because I only wanted to read in each song once [via document()], and then assign all the songs to a node-set(). I figured this would be more efficient (and easier to read and write) than having to read song data again and again each time I need to access what's in a song's XML file.

Does this make sense?

Well, I'm wondering how I can possibly eliminate my use of node-set() in this instance. Or does node-set() provide the easiest way to reuse data that is read from an arbitrary number of XML files?

If I am not being clear, please tell me, and I'll provide a concrete example.

 
Old May 1st, 2007, 07:06 PM
Authorized User
 
Join Date: Apr 2007
Posts: 38
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Here's a simplified example:
Code:
songs.xml        a.xml              b.xml              c.xml            
---------------  -----------------  -----------------  -----------------
<songs>          <song @title="a">  <song @title="b">  <song @title="c">
  <song>a</song>   <len>4:30</len>    <len>1:23</len>    <len>3:00</len>
  <song>b</song>   <lyrics>           <lyrics>           <lyrics>       
  <song>c</song>     blaa               asdasd             foobar
  ...              </lyrics>          </lyrics>          </lyrics>      
</songs>         </song>            </song>            </song>
Let's say I want my songs page to show the following lists:
1) songs sorted by title
2) songs sorted by length
3) songs sorted by first word in lyrics

How could I do this without either:
a) using node-set() or
b) reading in a song's xml file multiple times
?
 
Old May 2nd, 2007, 01:28 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Quote:
quote:Originally posted by tripecac
 I have managed to get rid of most of my node-set() occurances. However, I'm a bit stumped by one of the remaining ones.

I'm working on an album page. The album's XML lists songs by name. Each song has its data (length, lyrics, description) defined in an XML file whose name matches the song title. The XSLT for the album page does the following:

1) reads each song's data from its own XML file via document()
2) stores all songs' data in $songs variable using node-set()
3) references $songs in many locations
Not sure why you need node-set() for point 2. The document function returns a node set anyway.

--

Joe (Microsoft MVP - XML)





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





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