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>

工作示例

如果您还想要分钟而不是一小时的一小部分:

<?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 回答