|
Subject: RE: [xsl] filtering elements by single xpath From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Wed, 5 Apr 2006 18:12:06 +0100 |
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@xxxxxxx]
> Sent: 05 April 2006 15:46
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> 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[@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[@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"/>
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| RE: [xsl] filtering elements by sin, Michael Kay | Thread | RE: [xsl] filtering elements by sin, Tomas Kolaci |
| [xsl] QName as attribute value: how, Florent Georges | Date | RE: [xsl] filtering elements by sin, Michael Kay |
| Month |