2017-01-03 18 views
1

Я очень новичок в XSLT. Мне нужно преобразовать и копировать дочерние узлы 1000 раз, а также увеличивать число узлов, чтобы они были разными каждый раз.Как скопировать дочерний элемент n раз в файл XML с помощью XSLT

Входной XML:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="test.xsl"?> 
<catalog> 
    <cd> 
     <id>2017</id> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company>Columbia</company> 
     <price>10.90</price> 
     <year>1985</year> 
    </cd> 
</catalog> 

Мой XSLT: но это только копии раз

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

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

</xsl:stylesheet> 

Что мне нужно: Пожалуйста, помогите

<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="test.xsl"?> 
<catalog> 
    <cd> 
     <id>2017</id> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company>Columbia</company> 
     <price>10.90</price> 
     <year>1985</year> 
    </cd> 
    <cd> 
     <id>2018</id> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company>Columbia</company> 
     <price>10.90</price> 
     <year>1985</year> 
    </cd> 
    <cd> 
     <id>2019</id> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company>Columbia</company> 
     <price>10.90</price> 
     <year>1985</year> 
    </cd> 

    <!-- 997 more times with ID increment +1 each time --> 

</catalog> 

ответ

2

В XSLT 1.0 вы можете достичь этого, используя рекурсивный шаблон. Таким образом, шаблон повторно вызывает себя, каждый раз увеличивая параметр до достижения требуемого предела.

Попробуйте XSLT (замените параметр 5 с 1000, как это требуется)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:param name="total" select="5" /> 

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

<xsl:template match="cd" name="cd"> 
    <xsl:param name="count" select="1" /> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"> 
      <xsl:with-param name="count" select="$count" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
    <xsl:if test="$count &lt; $total"> 
     <xsl:apply-templates select="."> 
      <xsl:with-param name="count" select="$count + 1" /> 
     </xsl:apply-templates> 
    </xsl:if> 
</xsl:template> 

<xsl:template match="id"> 
    <xsl:param name="count" /> 
    <xsl:copy> 
     <xsl:value-of select="number() + $count - 1" /> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

EDIT: Если вы хотите, ту же логику, но и для других элементов в cd, просто изменить шаблон соответствия id, чтобы включить их в матч. Например ..

<xsl:template match="id|year"> 
    <xsl:param name="count" /> 
    <xsl:copy> 
     <xsl:value-of select="number() + $count - 1" /> 
    </xsl:copy> 
</xsl:template> 

Увидеть это в действии на http://xsltransform.net/gWEamLv

+0

Огромное спасибо Тим. Он работает отлично. – hln98

+0

Если я добавил еще один шаблон после match = "id" say match = "year" и do , я получаю NaN. Любая идея почему? – hln98

+0

Действительно ли тег '' содержит число или он пуст? –