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>
--~--