我想过滤元素集合(菜单项)。 我是为每个人做的。它看起来像这样:
<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 and $today <= $end">
<child>
<xsl:value-of select="current()"/>
</child>
</xsl:if>
</xsl:for-each>
</xsl:variable>
然后我通过以下代码使用它:
msxsl:node-set($actualMenus)/child
我尝试用xpath表达式替换上面的代码:
<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'), '-', '')
and translate(substring-before($menuDate, 'T'), '-', '') <= translate(substring-before(current()/cs:Properties/cs:CommercePropertyItem[cs:Key='EndDate']/cs:Value, 'T'), '-', '')]" />
不幸的是,它没有用。
有人可以帮我找出xpath表达式中的错误吗?
答案 0 :(得分:0)
您的代码的主要问题是您没有显示上下文(请参阅上面的评论,请更新您的问题)。但是,我的猜测是问题在于current()
。在xsl:for-each
中,current
- 函数指向for-each正在处理的当前节点。在新的select-expression中,current
- 函数指向 XPath表达式的上下文节点。它没有指向$menus
中的当前项,您应该使用上下文项表达式.
(尽管在您的情况下它是多余的)。
我通过添加看似可能的输入文档来尝试您的代码(再次,请用它更新您的问题!)。如果运行以下样式表,则会为两个xsl:value-of
指令输出相同的样式表。您可以针对任何输入文档运行样式表,它只需要变量$menus
(我将其包装在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 and $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'), '-', '')
and
translate(substring-before($menuDate, 'T'), '-', '')
<= translate(substring-before(cs:Properties/cs:CommercePropertyItem[cs:Key='EndDate']/cs:Value, 'T'), '-', '')
]" />
</xsl:template>
</xsl:stylesheet>
将输出:
StartDate2014-03-04T12:38EndDate2014-12-04T12:38
StartDate2014-03-04T12:38EndDate2014-12-04T12:38
您的表达与我的表达之间的区别在于我从您的表达式中删除了current()
。事实证明,在你的for-each循环中,这也是多余的,因为默认情况下获取焦点的节点与current()
返回的节点相同(但不要忘记删除领先斜线)。
我不确定为什么你希望它是一个单行的XPath。我不认为代码会变得更清晰,但当然,这是一个品味问题。