2012-03-28 68 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

相关问题