【问题标题】:Calculating Differences Using XSLT使用 XSLT 计算差异
【发布时间】:2012-02-20 16:56:28
【问题描述】:

我正在尝试使用 xslt 从 xml 文件中提取一些信息。我已经使用 xslt 数学函数来输出我正在迭代的某些操作的开始时间和结束时间之间的差异。但是,我不确定如何扩展它来计算下一个动作的开始时间和前一个动作的结束时间之间的差异。据我所知,您不能在 xslt 中重新分配变量。在传统语言中,我只是将最后一次遇到的时间存储为变量。如果有人能给我一些关于如何以更惯用的 xslt 方式执行此操作的指示,我将不胜感激。

这是我的数据文件的简化版本。

<Actions>
    <Action>
            <Start>1</Start>
            <End>10</End>
    </Action>
    <Action>
            <Start>13</Start>
            <End>16</End>
    </Action>
    <Action>
            <Start>20</Start>
            <End>24</End>
    </Action>
</Actions>

这是我当前的 xslt 转换,它只是在内部操作上有所不同。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="text" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/">
    <xsl:for-each select="Actions/Action">
        <xsl:value-of select="End - Start" /><xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我想看到的结果是

9
3
3
4
4

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:

    这个简短的转换(没有xsl:if,没有坐标轴):

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
    
     <xsl:variable name="vValues" select="/*/*/*"/>
    
     <xsl:template match="/">
         <xsl:for-each select="$vValues[position() >1]">
           <xsl:variable name="vPos" select="position()"/>
    
           <xsl:value-of select=". - $vValues[$vPos]"/>
           <xsl:text>&#xA;</xsl:text>
         </xsl:for-each>
     </xsl:template>
    </xsl:stylesheet>
    

    应用于提供的 XML 文档时

    <Actions>
        <Action>
            <Start>1</Start>
            <End>10</End>
        </Action>
        <Action>
            <Start>13</Start>
            <End>16</End>
        </Action>
        <Action>
            <Start>20</Start>
            <End>24</End>
        </Action>
    </Actions>
    

    产生想要的正确结果

    9
    3
    3
    4
    4
    

    【讨论】:

    • 你最喜欢的主题是什么,我的意思是性能考虑?
    • @KirillPolishchuk:如果您暗示此解决方案效率不高,请提供您的论据。我相信这个解决方案非常有效,甚至可以在流式(或惰性评估)模式下执行。在 XSLT 处理器不执行优化并且花费 O(N) 来评估 $vValues[k] 的情况下,我们可以将 $vValues 转换为另一个文档,其中所有值都包含在兄弟元素中,然后对于每个带有 position() &gt; 1 的元素输出. - preceding-sibling::*[1]。这个处理需要 O(N)。这种通用解决方案适用于许多不同的文档结构。
    【解决方案2】:

    用途:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="text"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="/Actions/Action">
        <xsl:value-of select="End - Start"/>
        <xsl:if test="following-sibling::Action">
          <xsl:text>&#xA;</xsl:text>
          <xsl:value-of select="following-sibling::Action/Start - End"/>
          <xsl:text>&#xA;</xsl:text>
        </xsl:if>
      </xsl:template>
    </xsl:stylesheet>
    

    输出:

    9
    3
    3
    4
    4
    

    【讨论】:

      猜你喜欢
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      相关资源
      最近更新 更多