xml - XSL for-each combine different operators -
i have xml-file, need filter in 3 ways:
1) colour shold red or green, other colours should filtered away
2) category category, except catb
3) status status, except missing or damaged
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="items.xsl"?> <list> <item> <description>green cata damaged</description> <include>n</include> <colour>green</colour> <category>cata</category> <status>damaged</status> </item> <item> <description>red cata ok</description> <include>y</include> <colour>red</colour> <category>cata</category> <status>ok</status> </item> <item> <description>green catb ok</description> <include>n</include> <colour>green</colour> <category>catb</category> <status>ok</status> </item> <item> <description>red catb ok</description> <include>n</include> <colour>red</colour> <category>catb</category> <status>ok</status> </item> <item> <description>blue catb ok</description> <include>n</include> <colour>blue</colour> <category>catc</category> <status>ok</status> </item> <item> <description>yellow catc ok</description> <include>n</include> <colour>yellow</colour> <category>catc</category> <status>ok</status> </item> <item> <description>green cata ok</description> <include>y</include> <colour>green</colour> <category>cata</category> <status>ok</status> </item> <item> <description>green catb missing</description> <include>n</include> <colour>green</colour> <category>catb</category> <status>missing</status> </item> <item> <description>red catb missing</description> <include>n</include> <colour>red</colour> <category>cata</category> <status>missing</status> </item> <item> <description>red catc damaged</description> <include>n</include> <colour>red</colour> <category>catc</category> <status>damaged</status> </item> </list>
i tried 1 for-each first (positive) condition, , for-each other 2 (negative) conditions - how on earth should combine them one? or, there better alternative use instead of for-each. googling , checking 3 books haven't given me answer, have strange feeling i'm totally wrong.....
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <list> <!-- "positive" statement <xsl:for-each select="list/item[colour='green' or colour='red']"> "negative" statement <xsl:for-each select="list/item[status!='missing'][status!='damaged'][category!='catb']"> --> <xsl:sort select="description"/> <itemline> <description><xsl:value-of select="description"/></description> <include><xsl:value-of select="include"/></include> <colour><xsl:value-of select="colour"/></colour> <category><xsl:value-of select="category"/></category> <status><xsl:value-of select="status"/></status> </itemline> </xsl:for-each> </list> </xsl:template> </xsl:stylesheet>
i have xml-file, need filter in 3 ways:
1) colour shold red or green, other colours should filtered away
2) category category, except catb
3) status status, except missing or damaged
i write way:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/*"> <xsl:apply-templates select= "item[colour[. = 'red' or . = 'green'] , not(category='catb' or status[. = 'missing' or . = 'damaged'])]"> <xsl:sort select="description"/> </xsl:apply-templates> </xsl:template> <xsl:template match="item"> <itemline><xsl:copy-of select="*"/></itemline> </xsl:template> </xsl:stylesheet>
in case important use <xsl:for-each>
(which not best xslt practice), above equivalent transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/*"> <xsl:for-each select= "item[colour[. = 'red' or . = 'green'] , not(category='catb' or status[. = 'missing' or . = 'damaged'])]"> <xsl:sort select="description"/> <itemline><xsl:copy-of select="*"/></itemline> </xsl:for-each> </xsl:template> </xsl:stylesheet>
both transformations, when applied on provided xml document, produce wanted, correct result:
<itemline> <description>green cata ok</description> <include>y</include> <colour>green</colour> <category>cata</category> <status>ok</status> </itemline> <itemline> <description>red cata ok</description> <include>y</include> <colour>red</colour> <category>cata</category> <status>ok</status> </itemline>
a useful short-cut expression:
instead of:
myelem = value1 or myelem = value2 or myelem = value3 or myelem = value4 or myelem = value5
one can write this:
contains('|value1|value2|value3|value4|value5|', concat('|',myelem, '|'))
or, if first argument string value of variable $myvalues
:
contains($myvalues, concat('|',myelem, '|'))
similarly, shortcut value of myelem
not 1 of many values:
not(contains($myvalues, concat('|',myelem, '|')))
Comments
Post a Comment