0

i am trying to calculate the ram ussage of my Tasks( named quantum in the ressource tags) so far i am using the code below but in the last part the ram of the children is only displayed spereatly, does someone have any idea on how to summand them together? and help would be appreciated

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
<body>
   <h2>Ram Usage Overview</h2>
  <table border="1">
    <tr>
      <th>Task</th>
      <th>Parent</th>
      <th>Path</th>
      <th>Ram(self)</th>
      <th>Ram(Children)</th>
    </tr>
    <xsl:for-each select="//start">
    <tr>
      <td>
        <xsl:value-of select="@name"/>
      </td>
      <td>
        <xsl:value-of select="ancestor::start[1]/@name"/>
      </td>
      <td>
        <xsl:for-each select="ancestor-or-self::start">
          <xsl:value-of select="@name"/>
          <xsl:if test="position() != last()">
            <xsl:text> -> </xsl:text>
          </xsl:if>
        </xsl:for-each>
      </td>
      <td>
        <xsl:value-of select="resource/@quantum"/>
      </td>
      <td>
          <xsl:for-each select="config/start">
            <xsl:value-of select="substring-before(resource/@quantum,'M')"/>
<!--this is where i want get the sum-->
          </xsl:for-each>
      </td>
    </tr>
    </xsl:for-each>
  </table>
</body>
 </html>
</xsl:template>

</xsl:stylesheet>

XML

<config name="init">
    <start name="A">
        <resource name="RAM" quantum="2024M"/>
        <config>
            <start name="B">
                <resource name="RAM" quantum="1024M"/>
            </start>
            <start name="C">
                <resource name="RAM" quantum="1024M"/>
                <config>
                    <start name="D">
                        <resource name="RAM" quantum="512M"/>
                    </start>
                    <start name="E">
                        <resource name="RAM" quantum="512M"/>
                        <config>
                            <start name="F">
                                <resource name="RAM" quantum="256M"/>
                                <config>
                                    <start name="H">
                                        <resource name="RAM" quantum="128M"/>
                                    </start>
                                    <start name="I">
                                        <resource name="RAM" quantum="128M"/>
                                    </start>
                                </config>
                            </start>
                            <start name="G">
                                <resource name="RAM" quantum="256M"/>
                            </start>
                        </config>
                    </start>
                </config>
            </start>
        </config>
    </start>
</config> 

i am very sorry for any formatting that may got screwed up

Tim C
  • 70,053
  • 14
  • 74
  • 93
Econ
  • 2,419
  • 3
  • 13
  • 18

3 Answers3

0

Assuming an XSLT 2.0 processor you can use

      <xsl:for-each select="config/start">
        <xsl:value-of select="substring-before(resource/@quantum,'M')"/>
      </xsl:for-each>
      <!-- compute sum -->
      <xsl:value-of select="sum(config/start/resource/@quantum/number(substring-before(., 'M')))"/>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • this produces an error for me saying"node test expected here" – Econ Aug 24 '16 at 12:39
  • You need to use an XSLT 2.0 processor like Saxon 9 or XmlPrime or Altova to use that approach. See the other answers if you are restricted to XSLT 1.0. – Martin Honnen Aug 24 '16 at 13:35
0

Assuming an XSLT 1.0 processor, try:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">

<xsl:template match="/">
    <html>
        <body>
            <h2>Ram Usage Overview</h2>
            <table border="1">
                <tr>
                    <th>Task</th>
                    <th>Parent</th>
                    <th>Path</th>
                    <th>Ram(self)</th>
                    <th>Ram(Children)</th>
                </tr>
                <xsl:for-each select="//start">
                    <tr>
                        <td>
                            <xsl:value-of select="@name"/>
                        </td>
                        <td>
                            <xsl:value-of select="ancestor::start[1]/@name"/>
                        </td>
                        <td>
                            <xsl:for-each select="ancestor-or-self::start">
                                <xsl:value-of select="@name"/>
                                <xsl:if test="position() != last()">
                                    <xsl:text> -> </xsl:text>
                                </xsl:if>
                            </xsl:for-each>
                        </td>
                        <td>
                            <xsl:value-of select="resource/@quantum"/>
                        </td>
                        <td>
                            <xsl:variable name="quanta">
                                <xsl:for-each select="config/start">
                                    <q>
                                        <xsl:value-of select="substring-before(resource/@quantum,'M')"/>
                                    </q>
                                </xsl:for-each>
                            </xsl:variable>
                            <xsl:value-of select="sum(exsl:node-set($quanta)/q)"/>
                            <xsl:text>M</xsl:text>
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

Applied to your input example, the (rendered) result will be:

enter image description here

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • this did help me in a way, i think i can see what you are doing, but it outputs 0M for everything, and this i cannot understand – Econ Aug 24 '16 at 14:27
  • @Econ Which processor are you using? If you don't know, see here how to find out: http://stackoverflow.com/questions/25244370/how-can-i-check-which-xslt-processor-is-being-used-in-solr/25245033#25245033 – michael.hor257k Aug 24 '16 at 14:36
0

If you can only use XSLT 1.0, then another way you can achieve this is ton use a recursive template to sum up the amended quantum attributes for a set of nodes.

<xsl:template name="resources">
    <xsl:param name="sum" select="0" />
    <xsl:param name="nodes" />

    <xsl:choose>
        <xsl:when test="$nodes">
            <xsl:call-template name="resources">
                <xsl:with-param name="sum" select="$sum + number(substring-before($nodes[1]/@quantum,'M'))" />
                <xsl:with-param name="nodes" select="$nodes[position() > 1]" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise><xsl:value-of select="$sum" /></xsl:otherwise>
    </xsl:choose>
</xsl:template>

To call it, to produce the sum, you would do this:

    <xsl:call-template name="resources">
        <xsl:with-param name="nodes" select="config/start/resource" />
    </xsl:call-template>

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
<body>
   <h2>Ram Usage Overview</h2>
  <table border="1">
    <tr>
      <th>Task</th>
      <th>Parent</th>
      <th>Path</th>
      <th>Ram(self)</th>
      <th>Ram(Children)</th>
    </tr>
    <xsl:for-each select="//start">
    <tr>
      <td>
        <xsl:value-of select="@name"/>
      </td>
      <td>
        <xsl:value-of select="ancestor::start[1]/@name"/>
      </td>
      <td>
        <xsl:for-each select="ancestor-or-self::start">
          <xsl:value-of select="@name"/>
          <xsl:if test="position() != last()">
            <xsl:text> -> </xsl:text>
          </xsl:if>
        </xsl:for-each>
      </td>
      <td>
        <xsl:value-of select="resource/@quantum"/>
      </td>
      <td>
        <xsl:call-template name="resources">
            <xsl:with-param name="nodes" select="config/start/resource" />
        </xsl:call-template>
      </td>
    </tr>
    </xsl:for-each>
  </table>
</body>
 </html>
</xsl:template>

<xsl:template name="resources">
    <xsl:param name="sum" select="0" />
    <xsl:param name="nodes" />
    <xsl:choose>
        <xsl:when test="$nodes">
            <xsl:call-template name="resources">
                <xsl:with-param name="sum" select="$sum + number(substring-before($nodes[1]/@quantum,'M'))" />
                <xsl:with-param name="nodes" select="$nodes[position() > 1]" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise><xsl:value-of select="$sum" /></xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>
Tim C
  • 70,053
  • 14
  • 74
  • 93