我有一系列节点,它们是父节点的直接子节点,我想循环这些节点,但将它们包装在 4 个“组”中。我可能没有非常清楚地表述这一点,所以这可能会有所帮助。
<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 似乎不允许我以不匹配的结束标记开始。
到目前为止,我找到的最接近的解决方案是 jquery 中的“修复”,但我宁愿不依赖 javascript 来格式化页面。
这个转变:
<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>
如果像我一样您需要转换按位置划分的源元素,请使用 xsl:for-each 而不是 xsl:copy:
<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>
面临同样的问题,就是想要输出
<div class="container">
<div class="row">
<div class="col">...</div>
<div class="col"/>...</div>
</div>
<div class="row">
...
</div>
</div>
来自 CXML(Collection XML)文件(http://gallery.clipflair.net/collection/activities.cxml - PivotViewer 显示背后的数据位于 http://gallery.clipflair.net/activity)
我根据这里的其他建议创造了以下内容,但是使用“模板”和“应用模板”的“模式”属性XSL标签,我相信这使它更干净:
<?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() < $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>
在 Altova XMLSpy 工具中运行时,上述输出(请注意,它使用 altova_samplexml 处理器指令来查找 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
...