我需要在xml树中获得前N个值,或者更好地说,我需要获得大于或等于第N个值的值,因此包括“ex-aequos”。我开始的xml就是这个
<?xml version="1.0" encoding="UTF-8"?>
<results>
<node type="prov" id="1" name="GLD">
<node type="gem" id ="2" name="Wageningen" value="300" />
<node type="gem" id ="3" name="Arnhem" value="500" />
<node type="gem" id ="4" name="Nijmegen" value="80" />
<node type="gem" id ="5" name="Beekbergen" value="40" />
<node type="gem" id ="6" name="Apeldoorn" value="3000" />
<node type="gem" id ="7" name="Rhenen" value="20" />
<node type="gem" id ="8" name="Bennekom" value="750" />
<node type="gem" id ="9" name="Velp" value="500" />
<node type="gem" id ="10" name="Ede" value="250" />
</node>
<node type="prov" id="11" name="LI">
<node type="gem" id ="12" name="Maastricht" value="1300" />
<node type="gem" id ="13" name="Heerlen" value="5010" />
<node type="gem" id ="14" name="Venlo" value="1300" />
<node type="gem" id ="15" name="Sittard" value="240" />
<node type="gem" id ="16" name="Roermond" value="100" />
<node type="gem" id ="17" name="Valkenburg" value="120" />
<node type="gem" id ="18" name="Geleen" value="1750" />
<node type="gem" id ="19" name="Venray" value="1300" />
<node type="gem" id ="20" name="Beek" value="850" />
</node>
</results>
以此结束,如果N = 3
<?xml version="1.0" encoding="UTF-8"?>
<results>
<provincie id="1" name="GLD">
<gemeente id="6" name="Apeldoorn" value="3000"/>
<gemeente id="8" name="Bennekom" value="750"/>
<gemeente id="3" name="Arnhem" value="500"/>
<gemeente id="9" name="Velp" value="500"/>
</provincie>
<provincie id="11" name="LI">
<gemeente id="13" name="Heerlen" value="5010"/>
<gemeente id="18" name="Geleen" value="1750"/>
<gemeente id="12" name="Maastricht" value="1300"/>
<gemeente id="14" name="Venlo" value="1300"/>
<gemeente id="19" name="Venray" value="1300"/>
</provincie>
</results>
当我使用下面的xslt时,结构是o.k.但它显然不会返回id为9,14和19的元素。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<results>
<xsl:apply-templates select="/results/node"/>
</results>"'
</xsl:template>
<xsl:template match="/results/node">
<xsl:variable name="provname" select="@name"/>
<xsl:variable name="provid" select="@id"/>
<provincie id="{$provid}" name="{$provname}">
<xsl:apply-templates select="./node">
<xsl:sort select="@value" data-type="number" order="descending"/>
</xsl:apply-templates>
</provincie>
</xsl:template>
<xsl:template match="results/node/node">
<xsl:variable name="gemname" select="@name"/>
<xsl:variable name="gemid" select="@id"/>
<xsl:variable name="value" select="@value"/>
<xsl:if test="position() <= 3">
<gemeente id="{$gemid}" name="{$gemname}" value="{$value}" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
不知道现在要遵循哪条路径。下面的代码不起作用。
<xsl:variable name="limitvalue" select="./node[3]/@value"/>
<xsl:if test="@value >= $limitvalue">
<gemeente id="{$gemid}" name="{$gemname}">
<xsl:value-of select="@value"/>
</gemeente>
</xsl:if>
任何帮助表示赞赏!
根据@ ThomasW的解决方案更新并允许设置limitrank。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<!--set limitrank as the rank that we use to cut off-->
<xsl:variable name="limitrank" select="3"/>
<xsl:template match="/">
<results>
<xsl:apply-templates select="/results/node"/>
</results>
</xsl:template>
<xsl:template match="/results/node">
<!-- We generate a string of decending @value numbers;
Each number covers exactly 5 characters (spaces are added if there are less than 5 digits) -->
<xsl:variable name="sortedValues">
<xsl:for-each select="node">
<xsl:sort select="@value" data-type="number" order="descending"/>
<!-- Here we add spaces and strip everything that exceeds 5 characters -->
<xsl:value-of select="substring(concat(@value,' '),1,5)"/>
</xsl:for-each>
</xsl:variable>
<!-- Now, we get the Nth number, which covers bytes (limitrank-1)*5+1 to limitrank*5;
So that we get a meaningful result if there were less than three numbers, we add two trailing zeroes -->
<xsl:variable name="limitValue" select="substring(concat($sortedValues,'0 0'),($limitrank - 1) * 5 + 1,5)"/>
<provincie>
<xsl:copy-of select="@id|@name"/>
<xsl:apply-templates select="node[@value >= $limitValue]">
<xsl:sort select="@value" data-type="number" order="descending"/>
</xsl:apply-templates>
</provincie>
</xsl:template>
<xsl:template match="results/node/node">
<gemeente>
<xsl:copy-of select="@id|@name|@value"/>
</gemeente>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
我不明白这个问题:对于每个省,你按照@value
对市政当局进行排序。然后你进入前三名,如果还有其他人与第三名@value
相同,你也可以包括那一名。是吗?
我相信这只能用一些字符串技巧来完成(参见代码中的注释):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<results>
<xsl:apply-templates select="/results/node"/>
</results>
</xsl:template>
<xsl:template match="/results/node">
<!-- We generate a string of decending @value numbers;
Each number covers exactly 5 characters (spaces are added if there are less than 5 digits) -->
<xsl:variable name="sortedValues">
<xsl:for-each select="node">
<xsl:sort select="@value" data-type="number" order="descending"/>
<!-- Here we add spaces and strip everything that exceeds 5 characters -->
<xsl:value-of select="substring(concat(@value,' '),1,5)"/>
</xsl:for-each>
</xsl:variable>
<!-- Now, we get the 3rd number, which covers characters 11 to 15;
So that we get a meaningful result if there were less than three numbers, we add two trailing zeroes -->
<xsl:variable name="limitValue" select="substring(concat($sortedValues,'0 0'),11,5)"/>
<provincie>
<xsl:copy-of select="@id|@name"/>
<xsl:apply-templates select="node[@value >= $limitValue]"/>
</provincie>
</xsl:template>
<xsl:template match="results/node/node">
<gemeente>
<xsl:copy-of select="@id|@name|@value"/>
</gemeente>
</xsl:template>
</xsl:stylesheet>
输出如下:
<?xml version="1.0" encoding="UTF-8"?>
<results>
<provincie id="1" name="GLD">
<gemeente id="3" name="Arnhem" value="500"/>
<gemeente id="6" name="Apeldoorn" value="3000"/>
<gemeente id="8" name="Bennekom" value="750"/>
<gemeente id="9" name="Velp" value="500"/>
</provincie>
<provincie id="11" name="LI">
<gemeente id="12" name="Maastricht" value="1300"/>
<gemeente id="13" name="Heerlen" value="5010"/>
<gemeente id="14" name="Venlo" value="1300"/>
<gemeente id="18" name="Geleen" value="1750"/>
<gemeente id="19" name="Venray" value="1300"/>
</provincie>
</results>
如果您希望对市政当局进行分类,那么当然您必须包含另一个xsl:sort
:
<provincie>
<xsl:copy-of select="@id|@name"/>
<xsl:apply-templates select="node[@value >= $limitValue]">
<xsl:sort select="@value" data-type="number" order="descending"/>
</xsl:apply-templates>
</provincie>