1

XSLT 1.0 を使用してこれを実現したいと考えています。時間は時間と分で表されます (例: 10:30 は基本的に 10 時間 30 分です)。それを時間 (10.50) のみに変換してから、すべての時間ノードの合計を計算する必要があります。

ソース XML ドキュメントは次のとおりです。

<Record>
   <hours>10:30</hours> 
   <hours>20:30</hours>
   <hours>10:60</hours> 
 </Record>

出力:

 <Record>
   <TotalHours>42.0</TotalHours>
 </Record>
4

2 に答える 2

2

Joepie の回答の解決策は、準拠している XSLT 1.0 プロセッサでコンパイル時の構文エラーを引き起こすことに注意してください (XSLT 2.0 プロセッサを使用している場合、コンパイル エラーなしでのみ実行できます)。

SAXON 6.5.4 from Michael Kay
Java version 1.6.0_31
Error at xsl:value-of on line 11 of file:/(Untitled):
  Error in expression                      sum(hours/number(substring-before(., ':'))) +                     sum(hours/number(substring-after(., ':'))) div 60                 : Unexpected token [<function>] in path expression
Transformation failed: Failed to compile stylesheet. 1 error detected.
Press any key to continue . . . 

これは、真に機能する真の XSLT 1.0 ソリューションです。

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

 <xsl:template match="/*">
     <xsl:copy>
       <xsl:variable name="vrtfTimes">
         <xsl:for-each select="*">
           <t>
               <xsl:value-of select=
               "substring-before(., ':') + substring-after(.,':') div 60"/>
           </t>
         </xsl:for-each>
       </xsl:variable>
       <TotalHours>
         <xsl:value-of select="floor(sum(ext:node-set($vrtfTimes)/*))"/>
       </TotalHours>
     </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<Record>
    <hours>10:30</hours>
    <hours>20:30</hours>
    <hours>10:60</hours>
</Record>

必要な正しい結果が生成されます。

<Record>
   <TotalHours>42</TotalHours>
</Record>

:

合計から時間だけでなく、残りの分も分として取得したい場合:

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

 <xsl:template match="/*">
   <xsl:copy>
     <xsl:variable name="vrtfTimes">
       <xsl:for-each select="*">
         <t>
           <xsl:value-of select=
             "substring-before(., ':') + substring-after(.,':') div 60"/>
         </t>
       </xsl:for-each>
     </xsl:variable>

     <xsl:variable name="vSum" select="sum(ext:node-set($vrtfTimes)/*)"/>
     <TotalHours>
             <xsl:value-of select="floor($vSum)"/>
             <xsl:text>:</xsl:text>
             <xsl:value-of select="round(60* ($vSum - floor($vSum)))"/>
     </TotalHours>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

この変換が次の (少し複雑な) XML ドキュメントに適用されると、次のようになります。

<Record>
    <hours>10:30</hours>
    <hours>20:30</hours>
    <hours>10:60</hours>
    <hours>1:15</hours>
    <hours>1:03</hours>
</Record>

正しい結果が生成されます。

<Record>
   <TotalHours>44:18</TotalHours>
</Record>
于 2013-03-29T03:00:17.490 に答える
0

XSLT 1.0 では:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>

    <xsl:template match="Record">
        <Record>
            <TotalHours>
                <xsl:value-of select="
                    sum(hours/number(substring-before(., ':'))) + 
                    sum(hours/number(substring-after(., ':'))) div 60
                "/>
            </TotalHours>
        </Record>
    </xsl:template>

</xsl:transform>

実施例

1 時間未満ではなく分数も必要な場合は、次のようにします。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>

    <xsl:template match="Record">
        <Record>
            <TotalHours>
                <xsl:value-of select="
                    concat(
                        sum(hours/number(substring-before(., ':'))) + floor(sum(hours/number(substring-after(., ':'))) div 60),   
                    '.',
                        format-number(floor(sum(hours/number(substring-after(., ':'))) mod 60), '00')
                    )
                "/>
            </TotalHours>
        </Record>
    </xsl:template>

</xsl:transform>

**作業例

于 2013-03-28T14:21:54.657 に答える