I have the following XMl file:

Code:
<Vehicles>
<Company name="Ford">
<Vehicletype Vtype="Suv">
<Price>12000</Price>
</Vehicletype>
</Company>
<Company name="Ford">
<Vehicletype Vtype="Truck">
<Price>20000</Price>
</Vehicletype>
</Company>
</Vehicles>

And I am trying to transform it to:

Code:
<Vehicles>
<Company name="Ford">
<Vehicletype Vtype="Suv">
<Price>12000</Price>
</Vehicletype>
<Vehicletype Vtype="Truck">
<Price>20000</Price>
</Vehicletype>
</Company>
</Vehicles>

Any help would be appreciated

Thanks Gary

Recommended Answers

All 2 Replies

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="/Vehicles">
       <Vehicles>
            <xsl:for-each select="Company[not(@name = following-sibling::Company/@name)]">
                 <xsl:copy>
                     <xsl:copy-of select="@*"/>
                     <xsl:variable name="name" select="@name"></xsl:variable>
                     <xsl:for-each select="/Vehicles/Company[@name = $name]">
                         <xsl:copy-of select="Vehicletype"/>
                     </xsl:for-each>
                 </xsl:copy> 
            </xsl:for-each>
       </Vehicles>
    </xsl:template>
    
</xsl:stylesheet>

The first solution is that of a programmer with a programming language to like java c c + +

for-each use sparingly

xsl has a loop to go through the whole contain xsl
any further costs for large xml files in the computer memory and computer time
see here http://en.wikipedia.org/wiki/Big_O_notation

a template describing the node as it is implemented

a calculation with not practical if you can avoid them

similar to the previous solution

xml test

<?xml version="1.0"?>
<Vehicles>
	<Company name="Ford">
		<Vehicletype Vtype="Suv">
			<Price>12000</Price>
		</Vehicletype>
	</Company>
	<Company name="Ford">
		<Vehicletype Vtype="Truck">
			<Price>20000</Price>
		</Vehicletype>
	</Company>
	<Company name="Fiat">
		<Vehicletype Vtype="Suv">
			<Price>3000</Price>
		</Vehicletype>
	</Company>
	<Company name="Fiat">
		<Vehicletype Vtype="Truck">
			<Price>4500</Price>
		</Vehicletype>
	</Company>
</Vehicles>

xsl

<?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="/">
		<Vehicles>
			<xsl:apply-templates select="Vehicles"/>
		</Vehicles>
	</xsl:template>
	<xsl:template match="Vehicles">
		<xsl:apply-templates select="Company[@name = preceding-sibling::Company/@name]"/>
	</xsl:template>
	<xsl:template match="Company">
		<xsl:variable name="co" select="@name"/>
		<Company name="{@name}">
			<xsl:apply-templates select="//Vehicletype[../@name= $co]"/>
			<!-- the other way 
			<xsl:apply-templates select="//Vehicletype[../@name= $co]" mode="copy"/>
		    -->
		</Company>
	</xsl:template>
	<xsl:template match="Vehicletype">
		<xsl:element name="{local-name(.)}">
			<xsl:attribute name="Vtype">
				<xsl:value-of select="@Vtype"/>
			</xsl:attribute>
			<xsl:apply-templates select="Price"/>
		</xsl:element>
	</xsl:template>
	<xsl:template match="Price">
		<xsl:element name="{local-name(.)}">
			<xsl:value-of select="."/>
		</xsl:element>
	</xsl:template>
	<xsl:template match="Vehicletype" mode="copy">
		<xsl:copy-of select="."/>
	</xsl:template>
</xsl:stylesheet>

result

<?xml version='1.0' ?>
<Vehicles>
  <Company name="Ford">
    <Vehicletype Vtype="Suv">
      <Price>12000</Price>
    </Vehicletype>
    <Vehicletype Vtype="Truck">
      <Price>20000</Price>
    </Vehicletype>
  </Company>
  <Company name="Fiat">
    <Vehicletype Vtype="Suv">
      <Price>3000</Price>
    </Vehicletype>
    <Vehicletype Vtype="Truck">
      <Price>4500</Price>
    </Vehicletype>
  </Company>
</Vehicles>
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.