1

私は以下のようなxmlを持っています(xslt 1.0を使用):

<?xml version="1.0" encoding="utf-8"?>
    <receives>
    <receive>
    <Year>2013</Year>
    <money>120</money>
    </receive>
    <receive>
    <Year>2013</Year>
    <money>150</money>
    </receive>
    <receive>
    <Year>2014</Year>
    <money>130</money>
    </receive>
    <receive>
    <Year>2011</Year>
    <money>120</money>
        </receive>
</receives>

年ごとにお金でグループ化したいのですが、年がリストにない場合(上記のxmlのように、2011はありません)、次のようにtotalamount=0で結果に2012を入れる必要があります。

<year>2011</year>
<totalamount>120</totalamount>
<year>2012</year>
<totalamount>0</totalamount>
<year>2013</year>
<totalamount>270</totalamount>
<year>2014</year>
<totalamount>130</totalamount>

現在、私は次のようにxsltを終了しました。

<xsl:key name="receive-key" match="receive" use="Year" />

<xsl:template match="/receives">
    <xsl:for-each
        select="receive[generate-id() = generate-id(key('receive-key', Year))]">
            <xsl:sort select="../receive[Year = current()/Year]/Year"></xsl:sort>
            <year>
                <xsl:value-of select="../receive[Year = current()/Year]/Year" />
            </year>
            <totalamount>
                <xsl:value-of select="sum(../receive[Year = current()/Year]/money)" />
            </totalamount>
    </xsl:for-each>
</xsl:template>

これは、既存の年でのみお金をグループ化できます。

<year>2011</year>
<totalamount>120</totalamount> 
<year>2013</year>
<totalamount>270</totalamount>
<year>2014</year>
<totalamount>130</totalamount>

挿入する方法についてのアイデア

<year>2012</year>
<totalamount>0</totalamount> 

結果に?

どうもありがとう!

4

1 に答える 1

2

これを行う1つの方法は、1年のパラメーターで呼び出される名前付きテンプレートを使用することです。キーに今年が存在しない場合は、空の値を出力して、次の年に呼び出します。

<xsl:template name="Year">
   <xsl:param name="Year"/>
   <xsl:if test="not(key('receive-key', $Year))">
      <year>
         <xsl:value-of select="$Year"/>
      </year>
      <totalamount>0</totalamount>
      <xsl:call-template name="Year">
         <xsl:with-param name="Year" select="$Year + 1"/>
      </xsl:call-template>
   </xsl:if>
</xsl:template>

したがって、キーに年が見つかるとすぐに、欠落している年の出力を停止します。

もう1つ注意すべき点は、XSLTの式の1つです。

<xsl:value-of select="../receive[Year = current()/Year]/Year" />

これは実際にはこれだけに簡略化できます!

<xsl:value-of select="Year"/>

同様に、効率のためにxsl:keyを利用するように合計を変更できます

<xsl:value-of select="sum(key('receive-key', Year)/money)"/>

これが完全なXSLTです

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="receive-key" match="receive" use="Year"/>

   <xsl:template match="/receives">
      <xsl:for-each select="receive[generate-id() = generate-id(key('receive-key', Year))]">
         <xsl:sort select="Year"/>
         <year>
            <xsl:value-of select="Year"/>
         </year>
         <totalamount>
            <xsl:value-of select="sum(key('receive-key', Year)/money)"/>
         </totalamount>
         <xsl:if test="position() != last()">
            <xsl:call-template name="Year">
               <xsl:with-param name="Year" select="number(Year) + 1"/>
            </xsl:call-template>
         </xsl:if>
      </xsl:for-each>
   </xsl:template>

   <xsl:template name="Year">
      <xsl:param name="Year"/>
      <xsl:if test="not(key('receive-key', $Year))">
         <year>
            <xsl:value-of select="$Year"/>
         </year>
         <totalamount>0</totalamount>
         <xsl:call-template name="Year">
            <xsl:with-param name="Year" select="$Year + 1"/>
         </xsl:call-template>
      </xsl:if>
   </xsl:template>
</xsl:stylesheet>

XMLに適用すると、次のように出力されます。

<year>2011</year>
<totalamount>120</totalamount>
<year>2012</year>
<totalamount>0</totalamount>
<year>2013</year>
<totalamount>270</totalamount>
<year>2014</year>
<totalamount>130</totalamount>
于 2012-12-28T09:19:25.973 に答える