Reputation: 149
I would like to filter nodes based on multiple condition.
<SHOP>
<zasoba>
<kod>10000</kod>
<vyrobca>APPLE</vyrobca>
<kategorie>
<kategoria>GOOD</kategoria>
</kategorie>
<obrazky/>
</zasoba>
<zasoba>
<kod>365</kod>
<vyrobca>HUAWEI</vyrobca>
<kategorie>
<kategoria>SOMETHING</kategoria>
</kategorie>
</zasoba>
<zasoba>
<kod>999</kod>
<vyrobca>HUAWEI</vyrobca>
<kategorie>
<kategoria>SOMETHING</kategoria>
</kategorie>
</zasoba>
<zasoba>
<kod>90000</kod>
<vyrobca>APPLE</vyrobca>
<kategorie>
<kategoria>SECONDGOOD</kategoria>
</kategorie>
<obrazky/>
</zasoba>
<zasoba>
<kod>304-R-MK</kod>
<vyrobca>APPLE</vyrobca>
<kategorie>
<kategoria>NOTGOOD</kategoria>
</kategorie>
</zasoba>
</SHOP>
Condition:
keep item in output if <vyrobca>
= APPLE and kategorie/kategoria
= GOOD or SECONDGOOD. Remove any other where <vyrobca>
= Apple and kategorie/kategoria
is any other value than GOOD or SECONDGOOD. Explanation: I would like to leave all APPLE items in the output, from these two categories.
second part of condition: leave in output everything when <vyrobca>
= HUAWEI. kategorie/kategoria
doesn't matter.
Example output from input above:
<SHOP>
<zasoba>
<kod>10000</kod>
<vyrobca>APPLE</vyrobca>
<kategorie>
<kategoria>GOOD</kategoria>
</kategorie>
<obrazky/>
</zasoba>
<zasoba>
<kod>365</kod>
<vyrobca>HUAWEI</vyrobca>
<kategorie>
<kategoria>SOMETHING</kategoria>
</kategorie>
</zasoba>
<zasoba>
<kod>999</kod>
<vyrobca>HUAWEI</vyrobca>
<kategorie>
<kategoria>SOMETHING</kategoria>
</kategorie>
</zasoba>
<zasoba>
<kod>90000</kod>
<vyrobca>APPLE</vyrobca>
<kategorie>
<kategoria>SECONDGOOD</kategoria>
</kategorie>
<obrazky/>
</zasoba>
</SHOP>
I am trying to use this match:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="zasoba[(not(vyrobca = 'APPLE') and not(kategorie/kategoria = 'GOOD' or kategorie/kategoria = 'SECONDGOOD')) or not(vyrobca = 'HUAWEI')]" />
</xsl:stylesheet>
But doesn't work. Operators can't be combined this way? I thought that (not(vyrobca = 'APPLE') and not(kategorie/kategoria = 'GOOD' or kategorie/kategoria = 'SECONDGOOD'))
should work, where I made exception for APPLE and the two categories.
Upvotes: 2
Views: 549
Reputation: 116992
Try this as your 2nd template:
<xsl:template match="zasoba[not(vyrobca = 'APPLE' and (kategorie/kategoria = 'GOOD' or kategorie/kategoria = 'SECONDGOOD') or vyrobca = 'HUAWEI')]" />
Explanation:
You want to include zasoba
nodes that meet the following conditions:
vyrobca = 'APPLE' and (kategorie/kategoria = 'GOOD' or kategorie/kategoria = 'SECONDGOOD')
or
vyrobca = 'HUAWEI'
In order to rewrite this as the predicate for the nodes to exclude, we just need to wrap the entire expression in not()
.
You have:
(not(vyrobca = 'APPLE') and not(kategorie/kategoria = 'GOOD' or kategorie/kategoria = 'SECONDGOOD')) or not(vyrobca = 'HUAWEI')
To understand this better, let's drop the part about kategorie/kategoria
and the redundant parentheses. This leaves as with:
not(vyrobca = 'APPLE') or not(vyrobca = 'HUAWEI')
which, according to DeMorgan's laws, is the equivalent of:
not ( vyrobca = 'APPLE' and vyrobca = 'HUAWEI' )
and this is of course true for any product with a single manufacturer.
Upvotes: 2