2013-07-08 47 views
2

我尝试做一个奇怪的转换。使用XSLT重复元素x的次数

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还是应该我宁愿只是处理这个代码?

+0

看到这里如何迭代从1到N:http://stackoverflow.com/questions/8701011/for-loop-in-xslt-page/8703214#8703214 – LarsH

回答

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> 
+0

这真是太棒了我真的不相信这是可能的。谢谢。 – Tone

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> 

它是基于以“迭代”值的增加命名模板的递归调用。如果不清楚的话只写评论。

+0

谢谢。我不相信这对XSLT 2.0来说是可能的,甚至不会梦想在1.0中尝试它。 – Tone