2012-07-03 24 views
0

我有一些XSLT映射用於某些轉換。我的問題是我怎麼能記住1.e;循環運行的次數。例如記住每個for循環中遞歸調用模板的最後一個計數

<xsl: for each> // This runs some 3 times 

<xsl: call-template > // This call template recursively runs 10 times 
<xsl: with- param > 
</xsl: call-template > 

<xsl: for each> 

在上面的例子外for循環運行3次和內呼叫模板recurively調用自身打印一些事情假設的10倍。所以我有3 * 10 = 30個週期。

我在這裏需要的是假設我有一個初始數字001,當for循環第一次運行時,它將調用將遞歸調用自身10次的模板。所以我打印的數字從001開始 - 010

下一次我運行循環時,我再次打印001-010 ans的數字,所以第三次。但我想要記住最後一個計數。假設在第一次迭代中我達到了010.因此在第二次迭代中,我將從011開始計數並打印到021. 並且在第三次,我將從022-032開始打印。

但是,任何人都可以告訴我我該怎麼做?我怎樣才能記住打印已經完成的最後一個值?

還有一件事我實際上僅限於XSLT1.0。這就是我必須像上面的例子一樣循環的原因。

這將是一個很大的幫助

我想要做的就是這樣的, 假設我有一個輸入XML作爲,

<A> 

<B from="123456781" to="123456782"> 
........ 
</B> 
<B from="123456781" to="123456785"> 
........ 
</B> 
<B from="123456788" to="123456788"> 
........ 
</B> 

</A> 

在上面的XML每個節點B與一個範圍相關聯「從到」。我需要創建與給定範圍內的數字一樣多的ouputB節點。而且我還必須獲得每個創建的outputB節點的唯一計數。例如輸出XML可以像,

<root> 

<outputB value="123456781" id="001"> // from first B node from="123456781" to="123456782" 
<outputB value="123456782" id="002"> 

<outputB value="123456781" id="003"> 
<outputB value="123456782" id="004">// from second B node from="123456781" to="123456785" 
<outputB value="123456783" id="005"> 
<outputB value="123456784" id="006"> 
<outputB value="123456785" id="007"> 

<outputB value="123456788" id="008">// from third B node from="123456788" to="123456788" 

</root> 

所以在上述的xsl我已遞歸地填充範圍值的從基礎上,並給參數雖然我除名的for-each每個輸入B節點上BU。從而創建輸出B節點的確切數量。但這裏的問題是在生成的XML中保持唯一的計數或ID。

謝謝:)

+0

XSLT是一種聲明式編譯語言,因此不支持累積賦值或覆蓋變量,因此您無法像描述的那樣在全局變量中追蹤這些變量。你究竟想要達到什麼目的?你能發佈一些XML和期望的輸出嗎? – Utkanos

+0

@Utkanos: - 我已經更新了這篇文章,並添加了輸入和輸出xml以更好地表達我需要獲得的成果。 –

回答

0

你不記得在XSLT值,甚至在非常特殊的情況下加起來,你走除外。但是,一般來說,你不需要。

所以,如果您有:

<xsl:for-each select="conditiona"> // This runs some 3 times 

那麼你有所有你需要提供一個計數:

<xsl:value-of select="count(conditiona)"/> // this displays 3 
0

當你調用模板,你只是通過在「深度」的參數。

<xsl:template Name="x"> 
    <xsl:param name="depth"> 

    <xsl:call-template name="x"> 
    <xsl:with param name="depth" select=="depth+1" /> 
    </xsl:call-template> 
</xsl:template> 

然後你爲你的外部循環做類似的事情。目前還不清楚你如何做這個循環,但你可能能夠使用position()。然後你想要的數字是位置()* 10 +深度。

+0

: - 我已經更新了輸入和輸出xmls的帖子。這可能會幫助你更好地理解我需要達到的目標。 –

0

這是怎麼回事?您可以在this XMLPlayground上運行它(請參閱輸出源)。它完全避免了for-each(在XSLT中最好避免)。

這裏有兩個關鍵概念:

  1. 重複,只要它的範圍需要
  2. 具有節點揭開序幕的過程中爲他們以下的兄弟姐妹,在同一個節點上的模板匹配,而不是讓根 - 匹配模板適用於所有B節點。這樣,「你在哪裏起牀?」關係可以通過傳遞參數來維護。這是非正統的,但工程。

代碼:

<!-- root - kick things off, for each B node --> 
<xsl:template match="/"> 
    <xsl:apply-templates select='//B[1]' /> 
</xsl:template> 

<!-- iteration content - B nodes --> 
<xsl:template match='B'> 

    <!-- recursion params --> 
    <xsl:param name='index' select='@from' /> 
    <xsl:param name='id' select='position()' /> 
    <xsl:param name='pos' select='position()' /> 

    <!-- output node --> 
    <outputB value='{$index}' id='{$id}' /> 

    <!-- now recurse for... --> 
    <xsl:choose> 

     <!-- ...as range requires --> 
     <xsl:when test='(@from and @to) and (not($index) or $index &lt; @to)'> 
      <xsl:apply-templates select='.'> 
       <xsl:with-param name='index' select='$index + 1' /> 
       <xsl:with-param name='id' select='$id + 1' /> 
      </xsl:apply-templates> 
     </xsl:when> 

     <!-- ...next B node, if there is one --> 
     <xsl:when test='following-sibling::B'> 
      <xsl:apply-templates select='following-sibling::B[1]'> 
       <xsl:with-param name='id' select='$id + 1' /> 
      </xsl:apply-templates> 
     </xsl:when> 
    </xsl:choose> 

</xsl:template> 

輸出:

<outputBs value="123456781" id="1"/> 
<outputBs value="123456782" id="2"/> 
<outputBs value="123456783" id="3"/> 
<outputBs value="123456781" id="4"/> 
<outputBs value="123456782" id="5"/> 
<outputBs value="123456783" id="6"/> 
<outputBs value="123456784" id="7"/> 
<outputBs value="123456785" id="8"/> 
<outputBs value="123456788" id="9"/> 
1

XSLT是一種功能性的語言。你不能用功能語言「記住」事物:沒有時間概念,沒有過去的事物記憶。您需要根據輸入中的某些內容來計算輸出中的所有內容。