i have an XML-file that i want to clean up with an XLST-file and save it as an new XML-file.
I am still a beginner but like to learn more. I have used a "for-each" function but i cant find what i am doing wrong.

He loops the file, but i get a repeating <sub> but i need all the <sub> elements

this is part of my original.xml:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot>
<index>
<title>title 1</title>
<sub>
<subtitle>subtitle1</subtitle>
<number>11111</number>
<description>description1</description>
<price>price1</price>
<image>12345</image>
<number>22222</number>
<description>description2</description>
<price>price2</price>
<image>12345</image>
<number>33333</number>
<description>description3</description>
<price>price3</price>
<image>12345</image>
<subtitle>subtitle2</subtitle>
<number>4444</number>
<description>description4</description>
<price>price4</price>
</sub>
<sub>
<subtitle>subtitle3</subtitle>
<number>55555</number>
<description>description5</description>
<price>price5</price>
<image>12345</image>
</sub>
</index>
</dataroot>

This is my XSLT:

<?xml version="1.0"?>
<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="/">
<index>
<xsl:for-each select="//sub">
<title>
<xsl:value-of select="//title"/>
</title>
<sub>
<subtitle>
<xsl:value-of select="//subtitle"/>
</subtitle>
<number>
<xsl:value-of select="//number"/>
</number>
<description>
<xsl:value-of select="//description"/>
</description>
<image>
<img>
<xsl:attribute name="href">
<xsl:value-of select="//image"/>
</xsl:attribute>
</img>
</image>
</sub>
</xsl:for-each>
</index>
</xsl:template>
</xsl:stylesheet>

This is the result:

<?xml version="1.0" encoding="UTF-8"?>
<index>
<title>title 1</title>
<sub>
<subtitle>subtitle1</subtitle>
<number>11111</number>
<description>description1</description>
<image>
<img href="12345"/>
</image>
</sub>
<title>title 1</title>
<sub>
<subtitle>subtitle1</subtitle>
<number>11111</number>
<description>description1</description>
<image>
<img href="12345"/>
</image>
</sub>
<title>title 1</title>
<sub>
<subtitle>subtitle1</subtitle>
<number>11111</number>
<description>description1</description>
<image>
<img href="12345"/>
</image>
</sub>
<title>title 1</title>
<sub>
<subtitle>subtitle1</subtitle>
<number>11111</number>
<description>description1</description>
<image>
<img href="12345"/>
</image>
</sub>
</index>


What i want is:
<?xml version="1.0" encoding="UTF-8"?>
<index>
<title>title 1</title>
<sub>
<subtitle>subtitle1</subtitle>
<number>11111</number>
<description>description1</description>
<image>
<img href="12345"/>
</image>
<number>22222</number>
<description>description2</description>
<image>
<img href="12345"/>
</image></sub>
<number>33333</number>
<description>description3</description>
<image>
<img href="12345"/>
</image>

Th output that you request is not a valid XML document i.e.

<?xml version="1.0" encoding="UTF-8"?>
<index>
<title>title 1</title>
<sub>
   <subtitle>subtitle1</subtitle>
   <number>11111</number>
   <description>description1</description>
   <image>
      <img href="12345"/>
   </image>
   <number>22222</number>
   <description>description2</description>
   <image>
      <img href="12345"/>
   </image>
</sub>
<number>33333</number>
<description>description3</description>
<image>
   <img href="12345"/>
</image>

Also it would help enormously if you would indent your XSLT and XML and also enclose them within code tags.

this is part of my original.xml:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot>
    <index>
        <title>title 1</title>
        <sub>
            <subtitle>subtitle1</subtitle>
            <number>11111</number>
            <description>description1</description>
            <price>price1</price>
            <image>12345</image>
            <number>22222</number>
            <description>description2</description>
            <price>price2</price>
            <image>12345</image>
            <number>33333</number>
            <description>description3</description>
            <price>price3</price>
            <image>12345</image>
        </sub>
        <sub>
            <subtitle>subtitle2</subtitle>
            <number>4444</number>
            <description>description4</description>
            <price>price4</price>
        </sub>
        <sub>
            <subtitle>subtitle3</subtitle>
            <number>55555</number>
            <description>description5</description>
            <price>price5</price>
            <image>12345</image>
        </sub>
        <sub>
            <subtitle>subtitle4</subtitle>
            <number>66666</number>
            <description>description6</description>
            <price>price6</price>
            <image>12345</image>
            <number>77777</number>
            <description>description7</description>
            <price>price7</price>
            <image>12345</image>
            <number>88888</number>
            <description>description8</description>
            <price>price8</price>
            <image>12345</image>
        </sub>
        <title>title 2</title>
        <sub>
            <subtitle>subtitle5</subtitle>
            <number>99999</number>
            <description>description9</description>
            <price>price9</price>
            <image>12345</image>
        </sub>
    </index>
</dataroot>

This is my XSLT:

<?xml version="1.0"?>
<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="/">
        <index>
            <xsl:for-each select="//sub">
                <title>
                    <xsl:value-of select="//title"/>
                </title>
                <sub>
                    <subtitle>
                        <xsl:value-of select="//subtitle"/>
                    </subtitle>
                    <number>
                        <xsl:value-of select="//number"/>
                    </number>
                    <description>
                        <xsl:value-of select="//description"/>
                    </description>
                    <image>
                        <img>
                            <xsl:attribute name="href">
                                <xsl:value-of select="//image"/>
                            </xsl:attribute>
                        </img>
                    </image>
                </sub>
            </xsl:for-each>
        </index>
    </xsl:template>
</xsl:stylesheet>

This is the result:

<?xml version="1.0" encoding="UTF-8"?>
<index>
   <title>title 1</title>
   <sub>
      <subtitle>subtitle1</subtitle>
      <number>11111</number>
      <description>description1</description>
      <image>
         <img href="12345"/>
      </image>
   </sub>
   <title>title 1</title>
   <sub>
      <subtitle>subtitle1</subtitle>
      <number>11111</number>
      <description>description1</description>
      <image>
         <img href="12345"/>
      </image>
   </sub>
   <title>title 1</title>
   <sub>
      <subtitle>subtitle1</subtitle>
      <number>11111</number>
      <description>description1</description>
      <image>
         <img href="12345"/>
      </image>
   </sub>
   <title>title 1</title>
   <sub>
      <subtitle>subtitle1</subtitle>
      <number>11111</number>
      <description>description1</description>
      <image>
         <img href="12345"/>
      </image>
   </sub>
</index>

The idea what i want is:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot>
    <index>
        <title>title 1</title>
        <sub>
            <subtitle>subtitle1</subtitle>
            <number>11111</number>
            <description>description1</description>
            <image>
                <img href="12345"/>
            </image>
            <number>22222</number>
            <description>description2</description>
            <image>
                <img href="12345"/>
            </image>
            <number>33333</number>
            <description>description3</description>
            <image>
                <img href="12345"/>
            </image>
        </sub>
        <sub>
            <subtitle>subtitle2</subtitle>
            <number>4444</number>
            <description>description4</description>
            <image>
                <img href="12345"/>
            </image>
        </sub>
        <sub>
            <subtitle>subtitle3</subtitle>
            <number>55555</number>
            <description>description5</description>
            <image>
                <img href="12345"/>
            </image>
        </sub>
        <sub>
            <subtitle>subtitle4</subtitle>
            <number>66666</number>
            <description>description6</description>
            <image>
                <img href="12345"/>
            </image>
            <number>77777</number>
            <description>description7</description>
            <image>
                <img href="12345"/>
            </image>
            <number>88888</number>
            <description>description8</description>
            <image>
                <img href="12345"/>
            </image>
        </sub>
        <title>title 2</title>
        <sub>
            <subtitle>subtitle1</subtitle>
            <number>99999</number>
            <description>description9</description>
            <image>
                <img href="12345"/>
            </image>
        </sub>
    </index>
</dataroot>

Edited 3 Years Ago by Reverend Jim: Fixed formatting

use for each for node set
think like a compiler vom top to button

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output indent="yes" method="xml"/>
	<xsl:template match="/">
		<index>
			<xsl:apply-templates select="dataroot"/>
		</index>
	</xsl:template>
	<xsl:template match="dataroot">
		<xsl:apply-templates select="index"/>
	</xsl:template>
	<xsl:template match="index">
		<title>
			<xsl:value-of select="title"/>
		</title>

		<xsl:apply-templates select="sub"/>
	</xsl:template>
	<xsl:template match="sub">
		<sub>
			<subtitle>
				<xsl:value-of select="subtitle"/>
			</subtitle>
			<number>
				<xsl:value-of select="number"/>
			</number>
			<description>
				<xsl:value-of select="description"/>
			</description>
			<image>
				<img>
					<xsl:attribute name="href">
						<xsl:value-of select="image"/>
					</xsl:attribute>
				</img>
			</image>
		</sub>
	</xsl:template>
</xsl:stylesheet>

Helmut Hagemann

This article has been dead for over six months. Start a new discussion instead.