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 October 2nd, 2003, 04:45 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
Default

I assume it won't work "out of the box" with msxml because of armen's comment
Quote:
quote:I used Saxon 6.5.2, which performs RTF to nodeset conversion implicitly if the version is set to 1.1; you may need to perform the conversion explicitly by using the EXSLT's node-set function or something similar.
which refers to the groups variable. You need to use the msxsl:node-set() function, so you would replace <xsl:with-param name="set" select="$groups/*"/> with <xsl:with-param name="set" select="msxsl:node-set($groups)/*"/>

armen - any comments?

hth
Phil
 
Old October 2nd, 2003, 04:50 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
Default

Forgot to mention that in order to use the msxsl:node-set() function you'll need to add a declaration of that namespace to the xsl:stylesheet element. The namespace you need is xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 
Old October 2nd, 2003, 05:17 AM
Authorized User
 
Join Date: Jun 2003
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default

hmmm... now intead of "expression must evaluate to a node-set" I get "exception occurred". Interestingly it still works in Netscape, I wasn't expecting Netscape to understand the MSXML specific call.

Here is the modified stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">

    <xsl:key name="number-to-person" match="person" use="number"/>
    <xsl:template match="/">
        <xsl:variable name="groups">
            <xsl:for-each select="/persons/person[generate-id() = generate-id(key('number-to-person', number)[1])]">
                <xsl:sort select="number"/>
                <xsl:variable name="current-group" select="/persons/person[number = current()/number]"/>
                <group>
                    <count>
                        <xsl:value-of select="count($current-group)"/>
                    </count>
                    <xsl:for-each select="$current-group">
                        <xsl:copy-of select="."/>
                    </xsl:for-each>
                </group>
            </xsl:for-each>
        </xsl:variable>

        <xsl:variable name="max-count">
            <xsl:call-template name="get-max">
                <xsl:with-param name="set" select="msxsl:node-set($groups)/*"/>

            </xsl:call-template>
        </xsl:variable>

        <persons>
            <xsl:call-template name="serialize">
                <xsl:with-param name="set" select="msxsl:node-set($groups)/*"/>

                <xsl:with-param name="max-group-count" select="$max-count"/>
            </xsl:call-template>
        </persons>
    </xsl:template>

(rest is as original)
 
Old October 2nd, 2003, 06:06 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
Default

Weird, I tried your modified version in XMLSpy and it worked just fine with MSXML3 and MSXML4, but it did crash using XML Spy's built-in engine (whatever that is). If I take out the msxsl:node-set() calls then it does indeed give the "expression must evaluate to a node-set" error.

I'll keep looking...
 
Old October 2nd, 2003, 07:22 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
Default

Sorry, but I've had no luck reproducing your error. Since I'm lost as to why armen's version doesn't seem to work for you, the only thing I can think to help you is to go back and amend my original attempt to incorporate calculation of the max number, using that max to determine when to move position. Here is the new version which now works if numbers are missing from the sequence.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:variable name="numRecs" select="count(/persons/person)"/>
  <xsl:variable name="maxNum">
    <xsl:call-template name="getMax">
      <xsl:with-param name="nodes" select="/persons/person/number"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:key name="nodesByNumber" match="person" use="number"/>
  <xsl:template match="/">
    <persons>
      <xsl:call-template name="genOutput">
        <xsl:with-param name="num" select="1"/>
        <xsl:with-param name="posn" select="1"/>
        <xsl:with-param name="recCount" select="1"/>
      </xsl:call-template>
    </persons>
  </xsl:template>
  <xsl:template name="genOutput">

    <xsl:param name="num"/>

    <xsl:param name="posn"/>
    <xsl:param name="recCount"/>
    <xsl:choose>
      <xsl:when test="$recCount &gt; $numRecs">

      </xsl:when>
      <xsl:when test="$num &gt; $maxNum">
        <!-- if the max number is exceeded then
    move back to number 1 and increment the position -->
        <xsl:call-template name="genOutput">
          <xsl:with-param name="num" select="1"/>
          <xsl:with-param name="posn" select="$posn+1"/>
          <xsl:with-param name="recCount" select="$recCount"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="key('nodesByNumber', $num)[$posn]">
            <!-- if a node with the given number and position exists, then
    copy it to result tree, move on to the next number, and increment recCount -->
            <xsl:copy-of select="key('nodesByNumber', $num)[$posn]"/>
            <xsl:call-template name="genOutput">
              <xsl:with-param name="num" select="$num+1"/>
              <xsl:with-param name="posn" select="$posn"/>
              <xsl:with-param name="recCount" select="$recCount+1"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <!-- if a node with the given number and position doesn't exist, then
        just move on to the next number, without incrementing recCount -->
            <xsl:call-template name="genOutput">
              <xsl:with-param name="num" select="$num+1"/>
              <xsl:with-param name="posn" select="$posn"/>
              <xsl:with-param name="recCount" select="$recCount"/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template name="getMax">
    <xsl:param name="nodes"/>
    <xsl:choose>
      <xsl:when test="not($nodes)">NaN</xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="$nodes">
          <xsl:sort data-type="number" order="descending"/>
          <xsl:if test="position() = 1">
            <xsl:value-of select="number(.)"/>
          </xsl:if>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
hth
Phil
 
Old October 2nd, 2003, 08:06 AM
Authorized User
 
Join Date: Jun 2003
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Wow, thats brilliant thanks!!

Its seems that MSXML 4 is causing my problems... using MSXML 3, both stylesheets work fine! So its all sorted, I can use MSXML 3 no problem. (wish I'd tried that earlier!)
 
Old October 2nd, 2003, 08:32 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
Default

strange that it works with MSXML 3 but not 4. Knowing Microsoft, there's probably a service pack that will fix it for you. Not sure what SP number they're up to at the moment for MSXML4.

Anyway, at least you have a working solution to your problem.:D It was an interesting exercise.
 
Old October 2nd, 2003, 08:35 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 147
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to armmarti
Default

O la la... I've missed the most interesting points in this thread :) Sorry guys, I was(am) busy, and couldn't look at the forum, but it's fine that you've found the solution.
Concerning the RTF to nodeset conversion: XSLT 2.0 promises that any RTF(more precisely, temporary tree) will be represented as a root node of the variable's content-tree (and the node can be later processed as any XML document node) and we'll finally get rid of that annoying conversions. I agree with pgtips that the problem is in that conversion.

Regards,
Armen





Similar Threads
Thread Thread Starter Forum Replies Last Post
alternate method of using MapQuest tennisdad1 Javascript How-To 2 January 23rd, 2006 08:06 PM
Ordering rows problem ami4quest6 SQL Language 10 October 12th, 2005 01:13 AM
Ordering a dataview Louisa VB.NET 2002/2003 Basics 1 November 11th, 2004 10:04 AM
Ordering results EstherMStrom XSLT 6 October 13th, 2004 09:50 AM
Ordering lists POL XSLT 3 June 9th, 2003 11:39 PM





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