2012-03-28 69 views
2

我有一系列節點是父節點的直接子節點我想循環這些節點,但將它們包裹在4個「組」中...我'這可能不會很清楚地表達,所以這可能會有所幫助;XSLT for-Each包裝div中的每個第n個項目

<span class="child01">@nodename</span> 
<span class="child02">@nodename</span> 
<span class="child03">@nodename</span> 
<span class="child04">@nodename</span> 
<span class="child05">@nodename</span> 
<span class="child06">@nodename</span> 
<span class="child07">@nodename</span> 
<span class="child08">@nodename</span> 
.. 
<span class="child32">@nodename</span> 
<span class="child33">@nodename</span> 
..and so on 

目標

<div class="group"> 
<span class="child01">@nodename</span> 
<span class="child02">@nodename</span> 
<span class="child03">@nodename</span> 
<span class="child04">@nodename</span> 
</div> 
<div class="group"> 
<span class="child05">@nodename</span> 
<span class="child06">@nodename</span> 
<span class="child07">@nodename</span> 
<span class="child08">@nodename</span> 
</div> 
<div class="group"> 
.. 
<span class="child32">@nodename</span> 
</div> 
<div class="group"> 
<span class="child33">@nodename</span> 
..and so on 

我已經試過這種思想的變化 - 包裝在打開和關閉組標籤很多,在一個新的關閉/打開對每第四個循環下降

<div class="group"> 
<xsl:for-each select="$currentPage/*"> 

<span> 
<xsl:value-of select="@nodeName" /> 
</span> 

<!-- 
      ============================================================= 
      After very 4th item 
      ============================================================= 
      --> 
      <xsl:if test="position() mod 4 = 0"> 
       <xsl:text></div><div class="page"></xsl:text> 
      </xsl:if> 

     </xsl:for-each> 
</div> 

但基本上,似乎XSLT不會讓我從一個關閉無與倫比的標記開始 我迄今發現的clkoset解決方案是jquery Wrapping a div around every three divs中的一個「修復」,但是我寧願不依靠javascript來格式化頁面。

+0

這是不工作的原因是,你仍然有可能產生在任何時候一個良好的文檔,我認爲。除非你告訴處理器,輸出是純文本 – 2014-08-15 16:58:23

回答

7

該轉化

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pNumCols" select="3"/> 

<xsl:template match="/*"> 
    <xsl:apply-templates select="span[position() mod $pNumCols = 1]"/> 
</xsl:template> 

<xsl:template match="span"> 
    <div> 
    <xsl:copy-of select= 
    ".|following-sibling::span[not(position() > $pNumCols -1)]"/> 
    </div> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加:

<t> 
    <span class="child01">@nodename</span> 
    <span class="child02">@nodename</span> 
    <span class="child03">@nodename</span> 
    <span class="child04">@nodename</span> 
    <span class="child05">@nodename</span> 
    <span class="child06">@nodename</span> 
    <span class="child07">@nodename</span> 
    <span class="child08">@nodename</span> .. 
    <span class="child32">@nodename</span> 
    <span class="child33">@nodename</span> 
</t> 

產生想要的結果

<div> 
    <span class="child01">@nodename</span> 
    <span class="child02">@nodename</span> 
    <span class="child03">@nodename</span> 
</div> 
<div> 
    <span class="child04">@nodename</span> 
    <span class="child05">@nodename</span> 
    <span class="child06">@nodename</span> 
</div> 
<div> 
    <span class="child07">@nodename</span> 
    <span class="child08">@nodename</span> 
    <span class="child32">@nodename</span> 
</div> 
<div> 
    <span class="child33">@nodename</span> 
</div> 
+0

花了我幾個讀數來弄清楚你在做什麼,並將它應用到我的真實代碼。但我明白了 - 我想。 實質上,初始模板(match = /。)用於調用第二個模板(match = span),但這樣做僅適用於每個xth計數的子級(確定爲變量pNumCols)。當第二個模板被調用時,它使用傳遞的子值並抓取其兄弟並輸出兄弟集合 - 所有這些同時包裝在所需的DIV標籤中。 – Elijha 2012-03-28 14:25:16

+0

@Elijha:是的,儘管官方術語略有不同:「*應用模板*」和「*參數*」。關鍵是讓節點進入「組」 - 首先定義組中的每個起始節點,然後整體處理組。可以在任意節點集上進行這種分組 - 其中節點不是兄弟節點。 – 2012-03-28 14:31:02

+0

@DimitreNovatchev它也會通過將$ pNumCols設置爲4來對每個第四個元素進行相同處理? – gorn 2013-06-17 10:26:05

0

如果你像我一樣需要改造正在按位置劃分,使用XSL源要素:對,每個替代的xsl:副本:

<xsl:template match="span"> 
    <ol> 
    <xsl:for-each select=".|following-sibling::span[not(position() > $pNumCols -1)]"/> 
     <li><xsl:value-of select="./text()"/></li> 
    </xsl:for-each> 
    </ol> 
</xsl:template> 
+0

也可以使用我猜 – 2014-08-15 16:59:37

0

由同一個面臨的問題,那就是希望輸出

<div class="container"> 
    <div class="row"> 
    <div class="col">...</div> 
    <div class="col"/>...</div> 
    </div> 
    <div class="row"> 
    ... 
    </div> 
</div> 

從CXML(集合XML)文件(http://gallery.clipflair.net/collection/activities.cxml - 在http://gallery.clipflair.net/activity的PivotViewer顯示背後的數據)

我杜撰了以下的基礎上,在這裏其他的建議,但我們在Altova的XMLSpy的工具運行時(請注意,它使用altova_samplexml

<?xml version="1.0" encoding="UTF-8"?> 
<?altova_samplexml http://gallery.clipflair.net/collection/activities.cxml?> 

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:cxml="http://schemas.microsoft.com/collection/metadata/2009" 
    exclude-result-prefixes="cxml" 
    > 

    <xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes"/> 
    <xsl:param name="COLUMNS" select="2"/> 

    <!-- ########################### --> 

    <xsl:template match="/"> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
     <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
     <title>ClipFlair Activities</title> 
     <link rel="stylesheet" type="text/css" href="style.css"/> 
     </head> 
     <body> 
     <xsl:apply-templates/> 
     </body> 
    </html> 
    </xsl:template> 

    <!-- ########################### --> 

    <xsl:template match="cxml:Collection"> 
    <div class="container"> 
     <xsl:apply-templates/> 
    </div> 
    </xsl:template> 

    <!-- ########################### --> 

    <xsl:template match="cxml:Items"> 
    <xsl:apply-templates select="cxml:Item[position() mod $COLUMNS = 1]" mode="row"/> 
    </xsl:template> 

    <!-- ########################### --> 

    <xsl:template match="cxml:Item" mode="row"> 
    <div class="row"> 
     <div>----------</div> 
     <xsl:apply-templates select=".|following-sibling::cxml:Item[position() &lt; $COLUMNS]" mode="col"/> 
    </div> 
    </xsl:template> 

    <xsl:template match="cxml:Item" mode="col"> 
    <xsl:variable name="URL" select="@Href"/> 
    <xsl:variable name="FILENAME" select="cxml:Facets/cxml:Facet[@Name='Filename']/cxml:String/@Value"/> 
    <div class="col"> 
     <xsl:value-of select="$FILENAME"/> --- <xsl:value-of select="$URL"/> 
    </div> 
    </xsl:template> 

    <!-- ########################### --> 

    <xsl:template match="*"> 
    <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="text()|@*"> 
    </xsl:template> 

</xsl:stylesheet> 

從上面的輸出:荷蘭國際集團的「模板」,「模式」屬性和「應用模板」 XSL標籤來代替,這使得它更清潔,我相信處理器指令來查找XML數據):


2DaysInParis-OpenActivity-CapRev-FR-EN.clipflair --- http://studio.clipflair.net/?activity=2DaysInParis-OpenActivity-CapRev-FR-EN.clipflair 

Abu_Dukhan-CapRev-A1-AR.clipflair --- http://studio.clipflair.net/?activity=Abu_Dukhan-CapRev-A1-AR.clipflair 


---------- 

AFarewellToArms-RevCap-C2-EN.clipflair --- http://studio.clipflair.net/?activity=AFarewellToArms-RevCap-C2-EN.clipflair 

agComhaireamhCountingRND.clipflair --- http://studio.clipflair.net/?activity=agComhaireamhCountingRND.clipflair 


---------- 

Al-imtihan-CapRev-B1-AR.clipflair --- http://studio.clipflair.net/?activity=Al-imtihan-CapRev-B1-AR.clipflair 

AlBar-Cap-B1-B2-IT.clipflair --- http://studio.clipflair.net/?activity=AlBar-Cap-B1-B2-IT.clipflair 

... 
+0

請注意,如果position()是一個基於0的索引而不是基於1的索引,那麼我們將使用模0,而不是模1 – 2014-08-15 18:33:22

+0

也注意到我用一個更簡單的表達式來獲得每個(N * i)+1項後面的N-1兄弟,其中i> = 0比其他帖子在這裏使用的要多,但我不得不使用lt;而不是<因爲Altova RaptorXML解析器(包含在Altova XMLSpy工具中)不接受它 – 2014-08-15 18:36:56

相關問題