问题描述
与此类似:重复元素 x 数量使用 XSLT 的次数
...但更进一步.
我已经有了一个包含每个记录"的 xml 文档.如果每条记录都有指定的重复次数(每条记录不同),XSLT 是否可以实现?
I'll already have a xml document with each 'record' in once. If each record has a specified number of times it needs to be duplicated (different for each record) would this be possible with XSLT?
例如:
<?xml version="1.0" standalone="yes"?>
<Parent>
<Record name="1">
<repeat>10</repeat>
<Child1>Value 1</Child1>
<Child2>Value 2</Child2>
</Record>
<Record name="2">
<repeat>5</repeat>
<Child1>Value 1</Child1>
<Child2>Value 2</Child2>
</Record>
<Record name="3">
<repeat>8</repeat>
<Child1>Value 1</Child1>
<Child2>Value 2</Child2>
</Record>
<Record name="4">
<repeat>26</repeat>
<Child1>Value 1</Child1>
<Child2>Value 2</Child2>
</Record>
</Parent>
XLST 可以使用repeat 标签来复制每条记录,这样记录1 被插入10 次,记录2 被插入5 次等等......?
Could XLST use the repeat tag to duplicate each record so that record 1 was inserted 10 times, record 2 inserted 5 times and so on ...?
我问,因为我可能需要设置学校圣诞卡印刷品,每个学生都订购一些他们自己的设计!
I ask as I may have to set up the school Christmas card print run with each pupil ordering a number of their own design!
推荐答案
使用 XSLT 3(由 Saxon 9.8 所有版本或 Altova 2017 和 2018 支持),您可以将其编写得像
Using XSLT 3 (as supported by Saxon 9.8 all editions or Altova 2017 and 2018) you can write that as compact as
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:mode on-no-match="shallow-copy" streamable="yes"/>
<xsl:output indent="yes"/>
<xsl:template match="Parent">
<xsl:copy>
<xsl:copy-of select="Record!copy-of()!(let $r := . return (1 to repeat)!$r)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
或者用
<xsl:template match="Record">
<xsl:copy-of select="copy-of()!(let $r := . return (1 to repeat)!$r)"/>
</xsl:template>
此外,正如评论中正确指出的那样,正常处理不需要 copy-of()
,仅用于流式处理,因此没有 streamable="yes"
xsl:mode
上的 code> 模板可以写成
Also, as pointed out rightly in the comments, the copy-of()
is not needed for normal processing, only for streaming, so without the streamable="yes"
on the xsl:mode
the template could be written as
<xsl:template match="Record">
<xsl:copy-of select="(1 to repeat)!current()"/>
</xsl:template>
使用 XSLT 2 你可以使用
Using XSLT 2 you can use
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Record">
<xsl:copy-of select="for $n in 1 to repeat return current()"/>
</xsl:template>
</xsl:stylesheet>
这篇关于使用 XSLT 转换 XML 条目指定的次数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!