xsl-list
[Top] [All Lists]

RE: [xsl] filtering elements by single xpath

2006-04-05 10:12:29
Try to avoid using copy-of here - copying nodes is expensive and often
unnecessary.

The simplest way is to avoid the inner predicate:

 <xsl:variable
     name="filtered-items"
     select="item[/root/item-filter/allow-items/@with-name = @name]"
 />

Saxon 8.x will do this automatically, but 6.x and other processors will
perform better if you pull the constant expression out of the loop:

<xsl:variable name="names"
select="/root/item-filter/allow-items/@with-name"/>
<xsl:variable
     name="filtered-items"
     select="item[$names = @name]"
 />

Better still is to use keys:

<xsl:key name="k" match="allow-items" use="@with-name"/>

then

select="item[key('k', @name)]"

Michael Kay
http://www.saxonica.com/


-----Original Message-----
From: Tomas Kolaci [mailto:kolaci(_at_)cncz(_dot_)cz] 
Sent: 05 April 2006 15:46
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] filtering elements by single xpath

 Hi!

 I'm using XSLT 1.1 and Saxon 6.5.3.

 I have following XML structure:

<root>
   <body>
      <item pos="1" name="n1"/>
      <item pos="2" name="n2"/>
      <item pos="3" name="n2"/>
      <item pos="4" name="n3"/>
      <item pos="5" name="n4"/>
   </body>
   <item-filter>
      <allow-items with-name="n2"/>
      <allow-items with-name="n4"/>
   </item-filter>
</root>

and in template:

<xsl:template match="body">
   <xsl:variable
     name="filtered-items"
     select="item[/root/item-filter/allow-items[(_at_)with-name = 
???/@name]"
   />
   ...
</xsl:template>

I'm trying to fill variable filtered-items with elements item 
with "allowed"
name (= there is an element /root/item-filter/allow-items 
with attribute
@with-name containing same value as item's @name)*, but I 
don't know how to
reach current item on ??? position in my select (function 
current() points
to current body element).

 I can handle it by sequential processing (copy of item is 
good enough for
my needs):

<xsl:variable name="filtered-items">
   <xsl:for-each select="item">
      <xsl:if
        test="/root/item-filter/allow-items[(_at_)with-name = 
current()/@name]">
         <xsl:copy-of select="."/>
      </xsl:if>
   </xsl:for-each>
</xsl:variable>

but I'm just curious if it is possible to achieve this by 
single xpath?

 Thanks in advance!

 Best regards, Tomas

*resultant filtered-items content for given example should be:

<item pos="2" name="n2"/>
<item pos="3" name="n2"/>
<item pos="5" name="n4"/>




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