'Create element with unique names

I have the following scenario:

There will be n number of the following tags within my root document.

<imagelist>
...
<imgp-src>0020104314-01-1.jpg</imgp-src>
<img-src>0020104314-01-2.jpg</img-src>
<img-src>0020104314-01-3.jpg</img-src>
<imgp-src>0020104314-01-4.jpg</imgp-src>
...
</imagelist>

I need to end up with the following, regardless of the source tag (img or imgp)

<img_url1>0020104314-01-1.jpg</img_url1>
<img_url2>0020104314-01-2.jpg</img_url2>
<img_url3>0020104314-01-3.jpg</img_url3>
<img_url4>0020104314-01-4.jpg</img_url4>

I've tried using a for-each loop with the position function to create the new elements. I've failed at every attempt.

Notice that the tag can start with either img or imgp. I need to name the resulting elements with a sequential identifier. I can rename the value, but can't seem to get the element renamed.

Can someone point me in the right direction.

I apologize in advance if this is a recurring question. I thought I had seen this answered before but can't seem to locate the answer.

Thank you.



Solution 1:[1]

If you strip the spaces you can use position():

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

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:template match="imgp-src | img-src">
        <xsl:element name="img_url{position()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

This assumes you have no other elements in imagelist. If you do, they will be counted as well and your numbering will be different. It's safer using <xsl:number> since you can choose exactly the nodes you want to count (and don't have to use strip-space):

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

    <xsl:output indent="yes"/>

    <xsl:template match="imgp-src | img-src">
        <xsl:variable name="number">
            <xsl:number count="imgp-src | img-src"/>
        </xsl:variable>
        <xsl:element name="img_url{$number}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

Solution 2:[2]

Use an approach like

<xsl:template match="imagelist">
  <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="imagelist/*">
  <xsl:element name="img_url{position()}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Martin Honnen