xsl-list
[Top] [All Lists]

RE: [xsl] Using "except" with node sequences

2008-08-04 11:30:57
Hi Ken and Michael,

It turns out the declaration was the problem.  The variable
$normalized_data was produced by a function that was typed as "node()*"
instead of "element()+".  Once I changed that, everything worked
perfectly.  Thanks for suggesting that.

Also, thanks Michael for your suggestion.  The code I posted was a
simplified form of my actual code, in which I'm combining two sequences
produced by two different functions, both of which are a bit complex for
a single predicate:

        select="$active_data except $new_data"

Both of these variables are constructed by functions executed on the
original $normalized_data variable.  Both use <xsl:sequence /> to return
a sequence of elements.  My impression was that by using <xsl:sequence
/>, I am returning references to the existing nodes in $normalized_data,
and not actually creating copies of those nodes in memory.  Is this in
fact the case?

An alternate method I considered was to create Boolean functions that
would allow me to construct a predicate like you suggested:

        select="$normalized_data[fn:active(.) and not(fn:new(.)]

But since I use $active_data and $new_data elsewhere in my stylesheet, I
decided against it, trying to avoid evaluating those Boolean functions
more than necessary.  

In general, which approach is better practice?  

Thanks,

-James



-----Original Message-----
From: G. Ken Holman [mailto:gkholman(_at_)CraneSoftwrights(_dot_)com] 
Sent: Monday, August 04, 2008 12:55 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Using "except" with node sequences

At 2008-08-04 12:38 -0500, James Sulak wrote:
I have a sequence of nodes stored in a variable,

Perhaps you only have a tree and not a sequence of nodes.

and I am attempting to filter it using an XPath expression that 
includes the "except" operator.  However, it's not working like I
expect it to.
...
I am attempting to filter it using this logic:

<olddata>
   <xsl:sequence 
select="$normalized_data[not(info/@action='delete')] except 
$normalized_data[info/@action='insert' or info/@action='modify']" />
</olddata>

I expect the returned sequence to include all of the nodes in 
$normalized_data that match the first condition and don't match the 
second condition (node 3).  What I am actually getting is all of the 
nodes in $normalized data.  Is there something about the "except" 
operator that I'm not understanding?

Nope!  Just a declaration issue I think.

You don't show your declaration of $normalized_data, so I'm going to 
assume you just made it a temporary tree and you didn't make it a 
variable of "data" elements.

My students of XSLT 2 who know XSLT 1 have had a problem with this 
when jumping on the temporary tree bandwagon, thinking they are 
getting variables of nodes, until I tell them about the use of the 
as= to direct the processor in the expected use of the variable.

I hope the example below helps illustrate the difference ... please 
let me know if this is not the source of your problem.  You can see 
the only difference is how I declared the nodes stored in the variable.

. . . . . . . . . . .  Ken


T:\ftemp>type james.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 version="2.0">

<xsl:output indent="yes"/>

<xsl:variable name="normalized_data">
<data id="1">
    <info action="delete" />
    <info action="insert" />
    <stuff />
</data>
<data id="2">
    <info action="insert" />
    <stuff />
</data>
<data id="3">
    <stuff />
</data>
</xsl:variable>

<xsl:variable name="normalized_data_ken" as="element(data)+">
<data id="1">
    <info action="delete" />
    <info action="insert" />
    <stuff />
</data>
<data id="2">
    <info action="insert" />
    <stuff />
</data>
<data id="3">
    <stuff />
</data>
</xsl:variable>

<xsl:template match="/">
   <results>
     <james>
       <olddata>
         <xsl:sequence 
select="$normalized_data[not(info/@action='delete')] except 
$normalized_data[info/@action='insert' or info/@action='modify']" />
       </olddata>
     </james>
     <ken>
         <xsl:sequence 
select="$normalized_data_ken[not(info/@action='delete')] except 
$normalized_data_ken[info/@action='insert' or info/@action='modify']" />
     </ken>
   </results>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>call xslt2 james.xsl james.xsl james.xml

T:\ftemp>type james.xml
<?xml version="1.0" encoding="UTF-8"?>
<results>
    <james>
       <olddata>
          <data id="1">
             <info action="delete"/>
             <info action="insert"/>
             <stuff/>
          </data>
          <data id="2">
             <info action="insert"/>
             <stuff/>
          </data>
          <data id="3">
             <stuff/>
          </data>
       </olddata>
    </james>
    <ken>
       <data id="3">
          <stuff/>
       </data>
    </ken>
</results>
T:\ftemp>rem Done!


--
Upcoming XSLT/XSL-FO hands-on courses:      Wellington, NZ 2009-01
World-wide corporate, govt. & user group XML, XSL and UBL training
RSS feeds:     publicly-available developer resources and training
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>