xmlツリーの上位N個の値を取得する必要があります。言い換えると、「ex-aequos」を含めて、N番目の値以上の値を取得する必要があります。私が始めた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を使用すると、構造は問題ありませんが、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>