2009-11-30 26 views
0

我使用XSLT 1.0來轉換某些XML文檔。我有一個問題做一兩件事,因爲我需要一些幫助,請:使用xslt創建xml(使用delta的每頁項目)

我有一組項目在我的XML文件是這樣的:

<item1>...</item1> 
<item2>...</item2> 
<!-- ... --> 
<itemN>...</itemN> 

我要創建這樣的基礎的在三角洲(每頁項目),例如增量爲三:

<page> 
    <item1>...</item1> 
    <item2>...</item2> 
    <item3>...</item3> 
</page> 
<page> 
    <item4>...</item4> 
    <item5>...</item5>  
    <item6>...</item6> 
</page> 

所以,基本上建立在XSLT一個XML結構,將放在每頁項目的固定數量。

如果試圖這樣的事情(爲了使用節點集):

<xsl:variable name="all_items_per_delta"> 
    <xsl:for-each select="item">  
    <!-- if position is one or if mod of 3 then insert a page node, 
     so for first contract and for 3th, 6th, 9th... item --> 
    <xsl:if test="position() = 1"> 
     <page> 
    </xsl:if> 
    <!-- in the meantime for every contract insert the contract node --> 
    <item> 
     <!-- ... --> 
    </item> 
    <!-- if position is one or if mod of 3 then insert a page node, 
     so for first item and for 3th, 6th, 9th... item--> 
    <xsl:if test="((position() mod 3) = 0)) and (position() != last())"> 
     </page> 
     <page> 
    </xsl:if>  
    <!-- if the position is last just end the page element --> 
    <xsl:if test="position() = last()"> ` 
     </page> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:variable> 

但是,這並不工作,因爲XSLT解析器說

'Expected end of tag 'page' 

,這是第一個<page>標籤我想補充。看起來我必須在同一行中結束頁面標籤</page>。與<xslt:if>不幸的是它不工作。

請指教,我怎樣才能製作這種樹片段結構,以便以後使用EXSL擴展提取節點集。 謝謝。

回答

2

它不起作用的原因是因爲XSLT本身必須是格式良好的XML;和例如這個:

<xsl:if test="..."> 
    </page> 
</xsl:if> 

不是格式良好的XML。簡而言之,你不能在一個結構中有一個開放標籤,並且在另一個結構中關閉一個。

現在就如何正確處理這個問題。一種簡單的方法是採用外循環中的每個_n_th元素,併爲其生成<page>元素;然後把該元素,下面ñ -1要素,即<page>內:

<xsl:for-each select="item[position() mod $n = 0]"> 
    <page> 
     <xsl:copy-of select=". | following-sibling::item[position() &lt; $n)]"> 
    </page> 
</xsl:for-each> 

或者,你可能想使用Muenchean method,通過position() mod $n分組項。

+0

+1,雖然我會表示它爲'follow-sibling :: item [position()< = $ n]' – Tomalak 2009-11-30 13:25:31

+1

其實它看起來我們都錯了,應該是'<$ n' - 我的代碼(自我和$ n-2以下),而你的產品會產生$ n + 1(自我和$ n以下)。 – 2009-11-30 16:03:19

+0

啊,好吧。 :)當然,你是對的。 – Tomalak 2009-12-01 10:32:40

2

我使用帕維爾的回答,稍微改變,對於分頁:

<xsl:param name="itemsPerPage" select="10"/> 

<xsl:for-each select="item[position() mod $itemsPerPage = 1 or position() = 1]"> 
    <page> 
    <xsl:for-each select=". | following-sibling::item[position() &lt; $itemsPerPage]" > 
    <!-- code to print out items --> 
    </xsl:for-each> 
    </page> 
</xsl:for-each> 

我認爲你需要or position() = 1在列表中包含第一項。另外,請注意mod $itemsPerPage = 1。例如,如果您希望每頁有10個項目,則需要在第一個for-each循環中選擇項目1,11,21等。