我正在使用XSLT 1.0来转换一些XML文档。我有一个问题要做一件事,因为我需要一些帮助,请:
我的XML文档中有一组项目如下:
<item1>...</item1>
<item2>...</item2>
<!-- ... -->
<itemN>...</itemN>
我想基于delta(每页项目数)创建类似这样的内容,例如delta为3:
<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扩展提取节点集。 谢谢。
答案 0 :(得分:2)
它不起作用的原因是因为XSLT本身必须是格式良好的XML;例如这样:
<xsl:if test="...">
</page>
</xsl:if>
不是格式良好的XML。简单地说,你不能在一个构造中包含一个开始标记,而在另一个构造中关闭一个。
现在关于如何正确处理这个问题。一种简单的方法是在外部循环中获取每个_n_th元素,并为其生成<page>
元素;然后将该元素和以下 n -1元素放在<page>
内:
<xsl:for-each select="item[position() mod $n = 0]">
<page>
<xsl:copy-of select=". | following-sibling::item[position() < $n)]">
</page>
</xsl:for-each>
或者,您可能希望使用Muenchean method,按position() mod $n
对项目进行分组。
答案 1 :(得分:2)
我使用Pavel的答案,略有改动,用于分页:
<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() < $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等。
答案 2 :(得分:0)
这需要一种在XSLT中进行分组的方法。 XSLT 1.0提供的支持很少,它需要Munchean方法的天才来解决它。 XSLT 2.0支持更多(但并非所有环境,例如某些MS环境)都支持XSLT2.0。
一些资源(来自helpfule XML专家)是:
http://www.jenitennison.com/xslt/grouping/