xslt - Turning an xsl:for-each in a single XPath expression -
i'd filter collection of elements (menu items). did for-each. looks this:
<xsl:variable name="actualmenus"> <xsl:for-each select="$menus"> <xsl:variable name ="startdate" select="current()/cs:properties/cs:commercepropertyitem[cs:key='startdate']/cs:value"/> <xsl:variable name ="enddate" select="current()/cs:properties/cs:commercepropertyitem[cs:key='enddate']/cs:value"/> <xsl:variable name="today" select="translate(substring-before($menudate, 't'), '-', '')"/> <xsl:variable name="start" select="translate(substring-before($startdate, 't'), '-', '')"/> <xsl:variable name="end" select="translate(substring-before($enddate, 't'), '-', '')"/> <xsl:if test="$start <= $today , $today <= $end"> <child> <xsl:value-of select="current()"/> </child> </xsl:if> </xsl:for-each> </xsl:variable>
and use following code: msxsl:node-set($actualmenus)/child
i try replace code above xpath expression:
<xsl:variable name="actualmenus" select="$menus[translate(substring-before(current()/cs:properties/cs:commercepropertyitem[cs:key='startdate']/cs:value, 't'), '-', '') <= translate(substring-before($menudate, 't'), '-', '') , translate(substring-before($menudate, 't'), '-', '') <= translate(substring-before(current()/cs:properties/cs:commercepropertyitem[cs:key='enddate']/cs:value, 't'), '-', '')]" />
unfortunatelly, doesn't work.
could me find out mistakes in xpath expression ?
the main issue code didn't show context (see comment above, please update question). however, guess issue lies current()
. in xsl:for-each
, current
-function points current node for-each processing. in new select-expression, current
-function points whatever context node outside xpath expression. does not point current item in $menus
, should use context item expression .
(though in case redundant).
i tried code adding seemed possible input document (again, please update question it!). if run following stylesheet, outputs same both xsl:value-of
instructions. can run stylesheet against input document, take variable $menus
(i wrapped in node-set
).
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:cs="http://whatever/cs" xmlns:ext="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="ext cs" version="1.0"> <xsl:output indent="yes" omit-xml-declaration="yes" /> <xsl:variable name="menudate" select="'2014-08-14t03:44'" /> <xsl:variable name="menus" > <cs:properties> <cs:commercepropertyitem> <cs:key>startdate</cs:key> <cs:value>2014-03-04t12:38</cs:value> </cs:commercepropertyitem> <cs:commercepropertyitem> <cs:key>enddate</cs:key> <cs:value>2014-12-04t12:38</cs:value> </cs:commercepropertyitem> </cs:properties> </xsl:variable> <xsl:template match="/" > <xsl:variable name="actualmenus"> <xsl:for-each select="ext:node-set($menus)"> <xsl:variable name ="startdate" select="current()/cs:properties/cs:commercepropertyitem[cs:key='startdate']/cs:value"/> <xsl:variable name ="enddate" select="current()/cs:properties/cs:commercepropertyitem[cs:key='enddate']/cs:value"/> <xsl:variable name="today" select="translate(substring-before($menudate, 't'), '-', '')"/> <xsl:variable name="start" select="translate(substring-before($startdate, 't'), '-', '')"/> <xsl:variable name="end" select="translate(substring-before($enddate, 't'), '-', '')"/> <xsl:if test="$start <= $today , $today <= $end"> <child> <xsl:value-of select="current()"/> </child> </xsl:if> </xsl:for-each> </xsl:variable> <!-- output text value of actual menu --> <xsl:value-of select="$actualmenus" /> <xsl:text>
</xsl:text> <!-- output text value of actual menu using single xpath --> <xsl:value-of select="ext:node-set($menus) [ translate(substring-before(cs:properties/cs:commercepropertyitem[cs:key='startdate']/cs:value, 't'), '-', '') <= translate(substring-before($menudate, 't'), '-', '') , translate(substring-before($menudate, 't'), '-', '') <= translate(substring-before(cs:properties/cs:commercepropertyitem[cs:key='enddate']/cs:value, 't'), '-', '') ]" /> </xsl:template> </xsl:stylesheet>
it output:
startdate2014-03-04t12:38enddate2014-12-04t12:38 startdate2014-03-04t12:38enddate2014-12-04t12:38
the difference between expression , mine remove current()
expression. which, turns out, redundant in for-each loop, node takes focus default same 1 returned current()
(but don't forget remove leading slash).
i not sure why want one-liner xpath. don't think code becomes clearer way, of course, matter of taste.
Comments
Post a Comment