2013-07-08 99 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