2013-07-31 21 views
8

Mam XML jak poniżej:Jak uzyskać maksymalną wartość mocy samego węzła w XSLT

<Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Name>HourlyReport</Name> 
    <Id>8</Id> 
    <TotalResults>1</TotalResults> 
    <TotalPages>1</TotalPages> 
    <Items> 
    <Item> 
     <Id>1</Id> 
     <Hour0>23</Hour0> 
     <Hour1>12</Hour1> 
     <Hour2>7</Hour2> 
     <Hour3>18</Hour3> 
     <Hour4>32</Hour4> 
     . 
     . 
     . 
     <Hour20>28</Hour20> 
     <Hour21>39</Hour21> 
     <Hour22>51</Hour22> 
     <Hour23>49</Hour23> 
    </Item> 
    </Items> 
</Report> 

Potrzebuję maksymalną wartość z wyżej XML przy użyciu XSLT. W powyższym przypadku maksymalna wartość to . Jak mogę to zdobyć? Możliwe jest również uzyskanie tej maksymalnej wartości w dowolnej zmiennej xslt, więc mogę jej użyć gdzie indziej. Nie mam żadnej drogi. Możesz użyć dowolnej wersji xslt 1.0 lub 2.0.

Odpowiedz

15

Biorąc XSLT 2.0, powinien wystarczyć do użycia

<xsl:variable name="max" select="max(/Report/Items/Item/*[starts-with(local-name(), 'Hour')]/xs:integer(.)"/> 

(gdzie arkusz stylów musiałby zadeklarować xmlns:xs="http://www.w3.org/2001/XMLSchema").

I z XSLT 1.0 Chciałbym po prostu uporządkować i mieć maksymalną wartość jak w

<xsl:variable name="max"> 
    <xsl:for-each select="/Report/Items/Item/*[starts-with(local-name(), 'Hour')]"> 
    <xsl:sort select="." data-type="number" order="descending"/> 
    <xsl:if test="position() = 1"><xsl:value-of select="."/></xsl:if> 
    </xsl:for-each> 
</xsl:variable> 
+0

Zobacz także: http://stackoverflow.com/a/10359896/59087 –

2

Ten XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:strip-space elements="*"/> 

    <!-- Putting the maximum hour from the list into a variable. --> 
    <xsl:variable name="max-hour"> 
     <xsl:call-template name="find-max"> 
     <!-- Select the list of hour elements you want to look at. --> 
     <xsl:with-param name="hours" select="//*[contains(local-name(), 'Hour')]"/> 
     </xsl:call-template> 
    </xsl:variable> 

    <xsl:template match="*"> 
    <!-- Displaying the result you are after. --> 
    <result> 
     <xsl:value-of select="$max-hour"/> 
    </result> 
    </xsl:template> 

    <!-- This template works recursively on the list of hours. --> 
    <xsl:template name="find-max"> 
    <xsl:param name="hours"/> 

    <!-- The value of the first hour in this list. --> 
    <xsl:variable name="this-hour"> 
     <xsl:value-of select="$hours[position() = 1]"/> 
    </xsl:variable> 

    <xsl:choose> 
     <xsl:when test="$hours"> 
     <!-- The maximum value of the remaining hours in this list. --> 
     <xsl:variable name="other-hours"> 
      <xsl:call-template name="find-max"> 
      <xsl:with-param name="hours" select="$hours[position() != 1]"/> 
      </xsl:call-template> 
     </xsl:variable> 

     <!-- Return the maximum of this hour and the remaining hours. --> 
     <xsl:choose> 
      <xsl:when test="$other-hours &gt; $this-hour"> 
      <xsl:value-of select="$other-hours"/> 
      </xsl:when> 
      <xsl:otherwise> 
      <xsl:value-of select="$this-hour"/> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:when> 

     <!-- We've reached the last hour in the list. --> 
     <xsl:otherwise/> 
    </xsl:choose> 

    </xsl:template> 

</xsl:stylesheet> 

daje następujący wynik:

<result>51</result> 
+0

dobry. Szablony, nawet rekursywne, są prawie zawsze szybsze niż w przypadku każdej lub innych konstrukcji pętli. – dartonw

3

w XSLT 2.0, ze przedmioty jako węzła kontekstowego korzystania

max(*[starts-with(local-name(), 'Hour')]) 
0

w XSLT 1 można użyć następujących rodzeństwo

<xsl:value-of select="/Report/Items/Item/*[starts-with(name(), 'Hour')][not(.&lt;following-sibling::*[starts-with(name(), 'Hour')])]"/>