2012-12-01 3 views
1

xml 트리에서 상위 N 값을 가져 오거나 더 좋다고 말하면 N 번째 값보다 크거나 같은 값을 가져와야합니다. "ex-aequos". I는 XSLT 이하 사용하면 I로 시작하여 XML이 경우, N = 3XSLT 정렬 문제 : 동일한 값을 가진 여러 노드가있는 상위 N

<?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> 

이것

<?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> 

이며,이 끝나야, 구조이다 오케이 그러나 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() &lt;= 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 &gt;= $limitvalue"> 
    <gemeente id="{$gemid}" name="{$gemname}"> 
     <xsl:value-of select="@value"/> 
    </gemeente> 
</xsl:if> 

도움을 주셨습니다.

업데이트 : @ ThomasW의 솔루션을 기반으로 제한을 설정할 수 있습니다.

<?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 &gt;= $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> 

답변

2

질문의 내 undestanding : 각 지방의 경우는 @value하여 지방 자치 단체를 정렬합니다. 그런 다음 상위 3 위를 차지하고 다른 하나가 같은 경우 @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 &gt;= $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 &gt;= $limitValue]"> 
     <xsl:sort select="@value" data-type="number" order="descending"/> 
     </xsl:apply-templates> 
    </provincie> 
+0

stion은 정확합니다. 나는 그것이 작동 할 때 속이기를 좋아하고, 당신은 그렇습니다. 예를 들어 처음 세 개의 값을 정렬 된 값으로 연결하기 만하면되는 것과 같은 몇 가지 최적화가 있습니다. – Graphileon

+0

문제가 해결되었다는 뜻입니까? 그렇다면 대답을 승인 된 것으로 표시해야합니다. –

+0

네가 맞아. 끝냈어. – Graphileon

관련 문제