Går det att göra urval i xpath på en nodelista. Ett sätt: Ett annat sätt:XPath predikat
typ: ("in" finns inte som operator i XPath)
//a[@id in //b/@ref]
dvs välj a noder som har ett attribut id som finns i b nodernas ref attribut.
från följande xml får man de två första a noderna
<b ref="id1"/>
<b ref="id2"/>
<a id="id1"/>
<a id="id2/>
<a id="id3/>Sv: XPath predikat
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="adrian.xsl" ?>
<root>
<b ref="id1"/>
<b ref="id2"/>
<a id="id1"/>
<a id="id2"/>
<a id="id3"/>
</root>
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
>
<xsl:template match="/">
<div>
<p>Before</p>
<xsl:for-each select="//a">
<xsl:variable name="a-node" select="." />
<xsl:variable name="a-id" select="@id" />
<xsl:for-each select="//b">
<xsl:variable name="b-node" select="." />
<xsl:variable name="b-ref" select="@ref" />
<xsl:if test="$a-id = $b-ref">
<xsl:copy-of select="$a-node" />
</xsl:if>
</xsl:for-each>
</xsl:for-each>
<p>After</p>
</div>
</xsl:template>
</xsl:stylesheet>
Sv: XPath predikat
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="//a[@id=//b/@ref]">
<xsl:copy-of select="."/>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
Jag har alltså bara bytt ut 'in' i ditt uttryck med '='. Detta funkar eftersom om den ena operanden är ett node-set så jämförs värdet av varje nod i detta med den andra operanden och true returneras om det finns minst en nod som matchar (http://www.w3.org/TR/xpath#booleans).
En annan metod som kanske är att föredra är att använda en key:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="referenced-ids" match="b/@ref" use="string(.)"/>
<xsl:template match="/">
<root>
<xsl:for-each select="//a[@id=key('referenced-ids',@id)]">
<xsl:copy-of select="."/>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
Här gås b-elementen bara igenom en gång (när key:n skapas) istället för att som i det förra exemplet en gång för varje a-element, vilket borde vara bättre ur prestandasynpunkt. (En bra XSLT-processor klarar säkert av att optimera sådana fall, men man vet aldrig.)