本文介绍了使用 XSLT 转换 XML 条目指定的次数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与此类似:重复元素 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 条目指定的次数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 21:30