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

Popular posts from this blog

matlab - error with cyclic autocorrelation function -

django - (fields.E300) Field defines a relation with model 'AbstractEmailUser' which is either not installed, or is abstract -

c# - What is a good .Net RefEdit control to use with ExcelDna? -