使用XSLT复制元素x次数

时间:2013-07-08 18:43:08

标签: xslt

我有一个奇怪的转变,我试图做。

XML看起来像这样:

<?xml version="1.0" standalone="yes"?>
<Parent>
    <RecordCount>4</RecordCount>
    <Record name="1">
        <Child1>Value 1</Child1>
        <Child2>Value 2</Child2>
    </Record>
</Parent>

这就是它需要的样子:

<?xml version="1.0" standalone="yes"?>
<Parent>
    <RecordCount>4</RecordCount>
    <Record name="1">
        <Child1>Value 1</Child1>
        <Child2>Value 2</Child2>
    </Record>
    <Record name="2">
        <Child1>Value 1</Child1>
        <Child2>Value 2</Child2>
    </Record>
    <Record name="3">
        <Child1>Value 1</Child1>
        <Child2>Value 2</Child2>
    </Record>
    <Record name="4">
        <Child1>Value 1</Child1>
        <Child2>Value 2</Child2>
    </Record>
</Parent>

使用XSLT甚至可以实现这样的功能,还是应该在代码中处理这个?

2 个答案:

答案 0 :(得分:1)

尝试关注xlst

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/Parent">
        <Parent>
            <xsl:variable name="count" select="RecordCount" />
            <xsl:call-template name="multiply">
                <xsl:with-param name="maxCount" select="$count" />
                <xsl:with-param name="nodeToCopy" select="Record" />
            </xsl:call-template>
        </Parent>
    </xsl:template>

    <xsl:template name="multiply">
        <xsl:param name="maxCount" />
        <xsl:param name="i" select="1" />
        <xsl:param name="nodeToCopy" />

        <xsl:choose>
            <xsl:when test="$i &lt;= $maxCount">
                <xsl:element name="{name($nodeToCopy)}">
                    <xsl:attribute name="name">
                        <xsl:value-of select="$i" />
                    </xsl:attribute>
                    <xsl:copy-of select="$nodeToCopy/child::*" />
                </xsl:element>

                <xsl:call-template name="multiply">
                    <xsl:with-param name="maxCount" select="$maxCount" />
                    <xsl:with-param name="nodeToCopy" select="$nodeToCopy" />
                    <xsl:with-param name="i" select="$i+1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise />
        </xsl:choose>

    </xsl:template>
</xsl:stylesheet>

它基于递归调用命名模板,增加了“迭代”值。如果不清楚则只需撰写评论。

答案 1 :(得分:1)

这是使用XSLT 2.0的另一种方式......

XML输入

<Parent>
    <RecordCount>4</RecordCount>
    <Record name="1">
        <Child1>Value 1</Child1>
        <Child2>Value 2</Child2>
    </Record>
</Parent>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="RecordCount">
        <xsl:variable name="record" select="../Record"/>
        <xsl:copy-of select="."/>
        <xsl:for-each select="1 to .">
            <xsl:apply-templates select="$record" mode="replicate">
                <xsl:with-param name="cnt" select="."/>
            </xsl:apply-templates>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="Record" mode="replicate">
        <xsl:param name="cnt"/>
        <Record name="{$cnt}">
            <xsl:apply-templates select="@* except @name|node()"/>
        </Record>
    </xsl:template>

    <xsl:template match="Record"/>

</xsl:stylesheet>

<强>输出

<Parent>
   <RecordCount>4</RecordCount>
   <Record name="1">
      <Child1>Value 1</Child1>
      <Child2>Value 2</Child2>
   </Record>
   <Record name="2">
      <Child1>Value 1</Child1>
      <Child2>Value 2</Child2>
   </Record>
   <Record name="3">
      <Child1>Value 1</Child1>
      <Child2>Value 2</Child2>
   </Record>
   <Record name="4">
      <Child1>Value 1</Child1>
      <Child2>Value 2</Child2>
   </Record>
</Parent>