Adrian
Adrian

Reputation: 2656

XSLT filter out element with multiple conditions

I have a big XML file and I want to filter out specified elements based on multiple conditions, specifically:

<title> contains 'K17' AND <category> contains 'APPLE'

So I started with something like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:g="http://base.google.com/ns/1.0">
 <xsl:output omit-xml-declaration="no" indent="yes" method="xml"/>

 <xsl:template match="node() | @*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="item[not(title/contains(text(),'K17')) and not(category/contains(text(),'APPLE'))]" />

</xsl:stylesheet>

Test XML:

<channel>
    <item>
        <title>K170001 Test 1</title>
        <category><![CDATA[APPLE &gt; MOBILE &gt; IPHONE]]></category>
    </item>
    <item>
        <title>K170002 Test 2</title>
        <category><![CDATA[APPLE &gt; MOBILE &gt; IPHONE]]></category>
    </item>
    <item>
        <title>K1x70003 Test 3</title>
        <category><![CDATA[APPLE &gt; MOBILE &gt; IPHONE]]></category>
    </item>
    <item>
        <title>K170004 Test 4</title>
        <category><![CDATA[APxPLE &gt; MOBILE &gt; IPHONE]]></category>
    </item>
</channel>

The last two element should be not in the final XML, because 'K1x70003' and 'APxPLE'.

And this is where my XSLT fails, it looks like AND operator works as an OR operator.

Upvotes: 2

Views: 2498

Answers (1)

Tim C
Tim C

Reputation: 70648

Your current expression has the wrong logic... "not(X) and not(Y)" is the same as "not(X or Y)" when you want "not(X and Y)" (which is the same as "not(X) or not(Y)")

Try this instead (note text() is not really necessary here)

<xsl:template match="item[not(contains(title,'K17') and contains(category,'APPLE'))]" />

Or just this....

<xsl:template match="item[not(contains(title,'K17')) or not(contains(category,'APPLE'))]" />

Do note that the syntax title/contains(text(),'K17')) should only be valid in XSLT 2.0.

Upvotes: 3

Related Questions