如何使用XSLT在数组中动态存储值并进行值的比较?

时间:2012-10-05 06:27:56

标签: xslt

我再次向你提供这样的要求。 你能看看这个吗?

<xml>
<test>
<BookID>
  <BookID1>
    <BookID2>
      0061AB
    </BookID2>
  </BookID1>
</BookID>
<amount>
  16
</amount>
</test>
<test>
<BookID>
  <BookID1>
    <BookID2>
      0062CD
    </BookID2>
  </BookID1>
</BookID>
<amount>
  2
</amount>
</test>
<test>
<BookID>
  <BookID1>
    <BookID2>
      0061AB
    </BookID2>
  </BookID1>
</BookID>
<amount>
  2
</amount>
</test>
</xml>

这里根据BookID的等值,我想添加金额值.....如上例所示,如果BookID的值是0061AB,那么金额的值应该是18。

修改(粘贴到答案)

输出应该是这样的

<xml>
  <test>
    <BookID>
      <BookID1>
        <BookID2>
          0061AB
        </BookID2>
      <BookID1>
    </BookID>
    <amount>
      18
    </amount>
  </test>
  <test>
    <BookID>
      <BookID1>
        <BookID2>
          0062CD
        </BookID2>
      <BookID1>
    </BookID>
    <amount>
      2
    </amount>
  </test>
</xml>

1 个答案:

答案 0 :(得分:0)

我假设你的意思是金额的总和。您可以使用xpath,如下所示

  <xsl:template match="/xml">
    <xsl:value-of select="sum(test[normalize-space(BookID)='0061AB']/amount)"/>
  </xsl:template>

修改

您可以根据我对previous question

的回答,使用变量或使用调用模板来参数化BookID

以下样式表

  <xsl:template match="/xml">
    <xsl:variable name="bookID" select="'0061AB'"/>
    <xsl:value-of select="sum(test[normalize-space(BookID)=$bookID]/amount)"/>
  </xsl:template>

编辑#2

您似乎现在正在grouping distinct elements之后并汇总总数。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <!-- the identity template -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="test">
        <xsl:variable name="bookID" select="normalize-space(BookID/text())" />
        <xsl:if test="not(preceding-sibling::test[normalize-space(BookID/text())=$bookID])">
            <test>
                <xsl:apply-templates />
            </test>
        </xsl:if>
        <!--Else `eat` the duplicate test node-->
    </xsl:template>

    <xsl:template match="amount">
        <amount>
            <xsl:variable name="bookID" select="normalize-space(../BookID/text())" />
            <xsl:value-of select="sum(//test[normalize-space(BookID/text())=$bookID]/amount)"/>
        </amount>
    </xsl:template>
</xsl:stylesheet>

生成输出

<xml>
    <test>
        <BookID>
            0061AB
        </BookID>
        <amount>18</amount>
    </test>
    <test>
        <BookID>
            0062CD
        </BookID>
        <amount>2</amount>
    </test>

</xml>

请您花点时间阅读FAQ

编辑3

此样式表将符合您的最新要求。

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

    <!-- the identity template -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="test">
        <xsl:variable name="bookID" select="normalize-space(BookID/BookID1/BookID2/text())" />
        <xsl:if test="not(preceding-sibling::test[normalize-space(BookID/BookID1/BookID2/text())=$bookID])">
            <test>
                <xsl:apply-templates />
            </test>
        </xsl:if>
        <!--Else `eat` the duplicate test node-->
    </xsl:template>

    <xsl:template match="amount">
        <amount>
            <xsl:variable name="bookID" select="normalize-space(../BookID/BookID1/BookID2/text())" />
            <xsl:value-of select="sum(//test[normalize-space(BookID/BookID1/BookID2/text())=$bookID]/amount)"/>
        </amount>
    </xsl:template>
</xsl:stylesheet>