XSLT проблемы с рекурсивной суммой - PullRequest
0 голосов
/ 12 августа 2011

Когда я пытаюсь рекурсивно суммировать атрибуты из нескольких узлов, он склеивается как строка: (


XML-файл (второй узел пробега включает первый узел пробега)

<mileage value="15000">
    <operation title="Replacing the engine oil" cost="500" />
    <sparepart title="Oil filter" cost="250" />
    <sparepart title="Motor oil" cost="1050" />
</mileage>
<mileage value="30000">
    <repeating mileage="15000" />
    <operation title="Replacement of spark" cost="1200" />
</mileage>

XSL-шаблон

<xsl:template match="mileage[@value]">
    <xsl:param name="sum" select="number(0)" />
    <xsl:variable name="milinkage"><xsl:value-of select="number(repeating/@mileage)" /></xsl:variable>
    <xsl:apply-templates select="parent::*/mileage[@value=$milinkage]"><xsl:with-param name="sum" select="number($sum)" /></xsl:apply-templates>
    <xsl:value-of select="number(sum(.//@cost))"/> <!--  + number($sum) -->
</xsl:template>

Результат склеивания 18001200 , но я хочу увидеть 3000 (1800 + 1200) Скажите, пожалуйста, что здесь не так?

Thanx!

Ответы [ 2 ]

0 голосов
/ 13 августа 2011

Удалите точку, и вы всегда увидите 3000, потому что все @costs (независимо от начальной точки) будут суммированы.

<xsl:value-of select="number(sum(//@cost))"/> <!--  + number($sum) -->

Вывод будет выглядеть следующим образом: 30003000

Но я предполагаю, что с вашим подходом что-то не так.Когда вы вызываете рекурсивный шаблон, вывод также будет напечатан так же, как шаблон вызывает сам себя в вашем случае.Вам нужно распечатать результат в конце вашей рекурсии

С учетом этого ввода:

<root>
<mileage value="15000">
    <operation title="Replacing the engine oil" cost="500" />
    <sparepart title="Oil filter" cost="250" />
    <sparepart title="Motor oil" cost="1050" />
</mileage>
<mileage value="30000">
    <repeating mileage="15000" />
    <operation title="Replacement of spark" cost="1200" />
</mileage>
</root>

и использование этого xslt:

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

<xsl:template match="/">
    <xsl:apply-templates select="root"/>
</xsl:template>

<xsl:template match="root">
    <xsl:apply-templates select="mileage[@value=30000]"/>
</xsl:template>

<xsl:template match="mileage[@value]">
    <xsl:param name="sum" select="number(0)" />
    <xsl:variable name="milinkage"><xsl:value-of select="number(repeating/@mileage)" /></xsl:variable>
    <xsl:variable name="newsum">
        <xsl:value-of select="number(sum(.//@cost)) + $sum"/>
    </xsl:variable>
    <xsl:apply-templates select="parent::*/mileage[@value=$milinkage]"><xsl:with-param name="sum" select="number($newsum)" /></xsl:apply-templates>
    <xsl:if test="not(parent::*/mileage[@value=$milinkage])">
        <xsl:value-of select="$newsum"/>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

дает правильный результат: 3000

0 голосов
/ 12 августа 2011

Вам нужны xmlns: exsl = "http://exslt.org/common"

<xsl:template match="/">
    <xsl:variable name="nodes">
        <xsl:apply-templates select="root/mileage[position()=last()]"/>
    </xsl:variable>
    <xsl:copy-of select="sum(exsl:node-set($nodes)/*[@cost]/@cost)"/>
</xsl:template>

<xsl:template match="mileage">
    <xsl:copy-of select="*[@cost]"/>
    <xsl:apply-templates select="../mileage[@value=current()/repeating/@mileage]"/>
</xsl:template>`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...