我想找到一个“更好”的解决方案来获取属性的最小值和最大值,并将它们保存到可访问的变量中。我也很乐意远离for-each-loop。怎么可能?
我的XML:
<Rows>
<Entry value1="16,423" value2="18,123" />
<Entry value1="423" value2="11,588" />
<Entry value1="1,168" value2="521" />
</Rows>
我的XSL:
<xsl:for-each select="Rows/Entry/@value1|Rows/Entry/@value2">
<xsl:sort select="." data-type="number" />
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:variable name="min" select="format-number(translate(.,',',''),'#')" />
</xsl:when>
<xsl:when test="position() = last()">
<xsl:variable name="max" select="format-number(translate(.,',',''),'#')" />
</xsl:when>
</xsl:choose>
</xsl:for-each>
所需的输出应该是$ min = 423和$ max = 18123作为数字并且可以在for-each-loops之外访问
答案 0 :(得分:2)
自2007年以来就有XSLT 2.0(由Saxon 9,AltovaXML,XmlPrime等XSLT处理器实现),您只需这样做(假设您的xmlns:xs="http://www.w3.org/2001/XMLSchema"
元素上有声明xsl:stylesheet
):< / p>
<xsl:variable name="min" select="min(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', ''))"/>
<xsl:variable name="max" select="max(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', ''))"/>
如果你真的想在一个变量中存储一个格式化的字符串,你当然也可以这样做。
<xsl:variable name="min" select="format-number(min(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', '')), '#')"/>
<xsl:variable name="max" select="format-number(max(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', '')), '#')"/>
对于XSLT 1.0,我认为使用for-each
进行排序是正确的方法,但您需要将xsl:variable
拉出for-each
,例如。
<xsl:variable name="min">
<xsl:for-each select="Rows/Entry/@value1|Rows/Entry/@value2">
<xsl:sort select="translate(., ',', '')" data-type="number"/>
<xsl:if test="position() = 1">
<xsl:value-of select="format-number(., '#')"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="max">
<xsl:for-each select="Rows/Entry/@value1|Rows/Entry/@value2">
<xsl:sort select="translate(., ',', '')" data-type="number"/>
<xsl:if test="position() = last()">
<xsl:value-of select="format-number(.,'#')" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
作为替代方案,您可以将for-each
替换为apply-templates
,然后编写匹配@value1 | @value2
的模板,但我认为在XSLT中使用推送样式可以更好地完成转换节点的大多数任务考虑找到最小值或最大值,for-each
没问题。
答案 1 :(得分:1)
我不确定它是否绝对正确,但我试过这个分钟
(/Rows/Entry/@value1|/Rows/Entry/@value2)[not((/Rows/Entry/@value1|/Rows/Entry/@value2) < .)]
这是最大的
(/Rows/Entry/@value1|/Rows/Entry/@value2)[not((/Rows/Entry/@value1|/Rows/Entry/@value2) > .)]
它给了我你提到的价值观。但为简化起见,我使用xml处理了没有“,”的值。