2012-02-20 104 views
3

我試圖使用xslt從xml文件中提取一些信息。我使用xslt數學函數來輸出我正在迭代的一些動作的開始和結束時間之間的差異。但是,我不確定我可以如何擴展它來計算下一個動作的開始時間和上一個動作的結束時間之間的差異。據我所知,你不能在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 

回答

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 
+0

那你最喜歡的話題,我的意思是性能考慮 – 2012-02-20 18:48:40

+0

@KirillPolishchuk:如果你暗示這個解決方案效率不高,請提供你的論點。我相信這個解決方案非常高效,甚至可以在流式(或懶惰評估)模式下執行。在XSLT處理器不執行優化並且爲了評估'$ vValues [k]'而採用O(N)的情況下,我們可以將'$ vValues'轉換爲另一個文檔,其中所有值都包含在兄弟元素中,然後對於每個文檔元素與'位置()> 1'輸出'。 - 之前的兄弟姐妹:: * [1]'。該處理採用O(N)。此通用解決方案適用於許多不同的文檔結構。 – 2012-02-20 19:09:37

1

用途:

<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