INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

XML transformation using XSLT - recursion

XML transformation using XSLT - recursion

(OP)
I would like to transform some XML using XSLT that involves recursion.

The source XML format is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<Products>
<Product Status="Updated" Type="Both">
<GUID>cca0c671-7070-411d-91e8-895361b53e19</GUID>
<ProductID>48936</ProductID>
<Description>Main Product 1</Description>
<Sequence>357</Sequence>
<LastModifiedTimeStamp>2013-06-06</LastModifiedTimeStamp>
<Parts>
<ProductPart PartType="Individual">
<Name>Individual Part 1-1</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>3</Quantity>
</ProductPart>
<ProductPart PartType="Individual">
<Name>Individual Part 1-2</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>1</Quantity>
</ProductPart>
<ProductPart PartType="SubProduct">
<Name>Sub Product 2</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>1</Quantity>
<SubParts>
<ProductPart PartType="Individual">
<Name>Individual Part 2-1</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>5</Quantity>
</ProductPart>
<ProductPart PartType="Individual">
<Name>Individual Part 2-2</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>10</Quantity>
</ProductPart>
<ProductPart PartType="SubProduct">
<Name>Sub Product 3</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>2</Quantity>
<SubParts>
<ProductPart PartType="Individual">
<Name>Individual Part 3-1</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>6</Quantity>
</ProductPart>
</SubParts>
</ProductPart>
</SubParts>
</ProductPart>
</Parts>
</Product>
</Products>

Target XML:
<Products>
<Product>
<GUID>cca0c671-7070-411d-91e8-895361b53e19</GUID>
<ProductID>48936</ProductID>
<Description>Main Product 1</Description>
<Sequence>357</Sequence>
<LastModifiedTimeStamp>2013-06-06</LastModifiedTimeStamp>
<Subproducts>
<ProductPart PartType="SubProduct">
<Name>Sub Product 2</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>1</Quantity>
<Subproducts>
<ProductPart PartType="SubProduct">
<Name>Sub Product 3</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>2</Quantity>
<Subproducts />
<Subparts>
<ProductPart PartType="Individual">
<Name>Individual Part 3-1</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>6</Quantity>
</ProductPart>
</Subparts>
</ProductPart>
</Subproducts>
<Subparts>
<ProductPart PartType="Individual">
<Name>Individual Part 2-1</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>5</Quantity>
</ProductPart>
<ProductPart PartType="Individual">
<Name>Individual Part 2-2</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>10</Quantity>
</ProductPart>
</Subparts>
</ProductPart>
</Subproducts>
<Subparts>
<ProductPart PartType="Individual">
<Name>Individual Part 1-1</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>3</Quantity>
</ProductPart>
<ProductPart PartType="Individual">
<Name>Individual Part 1-2</Name>
<GUID>a06ac00e-96ed-4c70-8040-6a280bfc8cf2</GUID>
<Quantity>1</Quantity>
</ProductPart>
</Subparts>
</Product>
</Products>

The XSLT I have written is as follows:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">

<xsl:template match='/Products'>
<Products>
<xsl:apply-templates select='Product'/>
</Products>
</xsl:template>

<xsl:template match='Product'>
<Product>
<GUID>
<xsl:value-of select='GUID'/>
</GUID>
<ProductID>
<xsl:value-of select='ProductID'/>
</ProductID>
<Description>
<xsl:value-of select='Description'/>
</Description>
<Sequence>
<xsl:value-of select='Sequence'/>
</Sequence>
<LastModifiedTimeStamp>
<xsl:value-of select='LastModifiedTimeStamp'/>
</LastModifiedTimeStamp>
<Subproducts>
<xsl:apply-templates select='Parts/ProductPart'>
<xsl:with-param name="SubPartParam" select="''" />
</xsl:apply-templates>
</Subproducts>
<Subparts>
<xsl:apply-templates select='Parts/ProductPart'>
<xsl:with-param name="SubPartParam" select="'Yes'" />
</xsl:apply-templates>
</Subparts>
</Product>
</xsl:template>

<xsl:template match='ProductPart'>
<xsl:param name="SubPartParam"/>

<xsl:choose>

<xsl:when test="($SubPartParam='' and @IngredientType='SubProduct')">
<ProductPart>
<xsl:attribute name='PartType'>
<xsl:value-of select='@PartType'/>
</xsl:attribute>
<xsl:apply-templates select='ProductPart' />
<Name>
<xsl:value-of select='Name'/>
</Name>
<GUID>
<xsl:value-of select='GUID'/>
</GUID>
<Quantity>
<xsl:value-of select='Quantity'/>
</Quantity>
</ProductPart>
</xsl:when>

<xsl:when test="($SubPartParam='Yes' and @IngredientType='Individual')">
<ProductPart>
<xsl:attribute name='PartType'>
<xsl:value-of select='@PartType'/>
</xsl:attribute>
<xsl:apply-templates select='ProductPart' />
<Name>
<xsl:value-of select='Name'/>
</Name>
<GUID>
<xsl:value-of select='GUID'/>
</GUID>
<Quantity>
<xsl:value-of select='Quantity'/>
</Quantity>
</ProductPart>
</xsl:when>

</xsl:choose>

</xsl:template>

</xsl:stylesheet>
Could someone please help me with the XSLT? I haven't done much work on XML transformation before and am in desperate need for help

RE: XML transformation using XSLT - recursion

Your XSLT showed that you need to study XPath predicates and Attribute Value Templates.

I modified your style sheet as follows:

CODE --> XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output indent="yes"/>

<xsl:template match="/Products">
	<Products>
		<xsl:apply-templates select="Product"/>
	</Products>
</xsl:template>

<xsl:template match="Product">
	<Product>
		<GUID>
			<xsl:value-of select="GUID"/>
		</GUID>
		<ProductID>
			<xsl:value-of select="ProductID"/>
		</ProductID>
		<Description>
			<xsl:value-of select="Description"/>
		</Description>
		<Sequence>
			<xsl:value-of select="Sequence"/>
		</Sequence>
		<LastModifiedTimeStamp>
			<xsl:value-of select="LastModifiedTimeStamp"/>
		</LastModifiedTimeStamp>
		<Subproducts>
			<xsl:apply-templates select="Parts/ProductPart[@PartType='SubProduct']"/>
		</Subproducts>
		<Subparts>
			<xsl:apply-templates select="Parts/ProductPart[@PartType!='SubProduct']"/>
		</Subparts>
	</Product>
</xsl:template>

<xsl:template match="ProductPart">
	<ProductPart PartType="{@PartType}">
		<Name>
			<xsl:value-of select="Name"/>
		</Name>
		<GUID>
			<xsl:value-of select="GUID"/>
		</GUID>
		<Quantity>
			<xsl:value-of select="Quantity"/>
		</Quantity>
		<xsl:if test="SubParts/ProductPart[@PartType='SubProduct']">
		<Subproducts>
			<xsl:apply-templates select="SubParts/ProductPart[@PartType='SubProduct']"/>
		</Subproducts>
		</xsl:if>
		<xsl:if test="SubParts/ProductPart[@PartType!='SubProduct']">
		<Subparts>
			<xsl:apply-templates select="SubParts/ProductPart[@PartType!='SubProduct']"/>
		</Subparts>
		</xsl:if>
	</ProductPart>
</xsl:template>
</xsl:stylesheet>SubParts/ProductPart[@PartType!='SubProduct']"/>
		</Subparts>
		</xsl:if>
	</ProductPart>
</xsl:template>
</xsl:stylesheet> 

The <xsl:if> tests were simply to avoid having self-closing (i.e. empty) tags appear since your desired XML did not show empty tages.

I hope this helps your understanding.

Tom Morrison
Hill Country Software

RE: XML transformation using XSLT - recursion

Oops. There seems to have been a little extra cruft at the end of my example code Please ignore...

Tom Morrison
Hill Country Software

RE: XML transformation using XSLT - recursion

(OP)
thanks. that solved my problem

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close