我以前发布的这个问题,在这个门户网站,我得到了一个满意的解决方案。 现在我的问题已经演变了一下。 如果我在链接的问题XML进行更新,以我的号码与他们等相关联的单位cm
, m
, in
, px
等,所以新的XML是:
<root>
<a>
<b>12cm</b>
<e>hello</e>
</a>
<a>
<b>11m</b>
<e>how</e>
</a>
<a>
<c>13m</c>
<f>are</f>
</a>
<a>
<b>21cm</b>
<f>you</f>
</a>
<a>
<d>22cm</d>
<e>hello</e>
</a>
<a>
<c>14m</c>
<f>hi</f>
</a>
现在,我首先需要类似的单元转换论文编号(让说cm
)之前,我可以对它们进行排序,找到最大数量。 我怎样才能做到这一点?
我用下面的XSL我以前的问题,但现在我需要更新它使我能够对它们进行排序之前转换我的号码。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="root">
<xsl:for-each select="a/b | a/c | a/d">
<xsl:sort select="." order="descending"/> <!-- find the unit and transform it in centimeters before sorting -->
<xsl:if test="position() = 1">
<highest><xsl:copy-of select="."/></highest>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
注:我使用XSLT 1.0
我已经适应Dimitre Novatchev的答案在这里( XSLT排序输出XML )。
如果应用以下样式表到你的输入:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:variable name="letters" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:template match="/">
<xsl:variable name="unsorted">
<root>
<xsl:for-each select="root/a/*">
<xsl:choose>
<xsl:when test="string(number(translate(., $letters, '')))!='NaN' and translate(current(), '0123456789', '') = 'cm'">
<xsl:element name="{local-name()}">
<xsl:attribute name="oldvalue"><xsl:value-of select="."/></xsl:attribute>
<xsl:value-of select="number(translate(., $letters, ''))"/>
</xsl:element>
</xsl:when>
<xsl:when test="string(number(translate(., $letters, '')))!='NaN' and translate(current(), '0123456789', '') = 'm'">
<xsl:element name="{local-name()}">
<xsl:attribute name="oldvalue"><xsl:value-of select="."/></xsl:attribute>
<xsl:value-of select="number(translate(., $letters, '')*100)"/>
</xsl:element>
</xsl:when>
<xsl:when test="string(number(translate(., $letters, '')))!='NaN' and translate(current(), '0123456789', '') = 'in'">
<xsl:element name="{local-name()}">
<xsl:attribute name="oldvalue"><xsl:value-of select="."/></xsl:attribute>
<xsl:value-of select="number(translate(., $letters, '')*2.54)"/>
</xsl:element>
</xsl:when>
<xsl:when test="string(number(translate(., $letters, '')))!='NaN' and translate(current(), '0123456789', '') = 'px'">
<xsl:attribute name="oldvalue"><xsl:value-of select="."/></xsl:attribute>
<xsl:element name="{local-name()}">
<xsl:value-of select="number(translate(., $letters, '') div 37.795275591)"/>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</root>
</xsl:variable>
<xsl:variable name="vPass1" select="ext:node-set($unsorted)"/>
<xsl:apply-templates select="$vPass1/*"/>
</xsl:template>
<xsl:template match="root">
<root>
<xsl:for-each select="*">
<xsl:sort select="." data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<highest><xsl:copy-of select="."/></highest>
</xsl:if>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
它输出:
<root>
<highest>
<c oldvalue="14m">1400</c>
</highest>
</root>
你喜欢疯狂复杂的表达式? 举个例子,假设你只有单位“米”,“厘米”和“毫米”的考虑,你可以写你的那种表达这样的....
<xsl:sort select="number(translate(., 'cm', '')) *
(
(translate(., '1234567890', '') = 'mm') * 1 +
(translate(., '1234567890', '') = 'cm') * 10 +
(translate(., '1234567890', '') = 'm') * 1000
)"
order="descending"/>
这需要在一个数字表达式优势的事实,真正被评估为1,假为0。它是一切转换成毫米做排序这种特殊情况。
这避免了使用节点集,但是这可能是你可以对自己有利来的一句话.....