I am converting same multi tag elements into different records.
In this i am using XSLT.
I need help in XSLT.
i am getting first tag result is correct, nut idont know why second tags not getting.
Explanation::
*In First CD :: Single atrist to many titles. I want to split this into defferent tags based on title.
In Second CD:: First title by First artist and second title by second artist. I need this also in different(two) CD tags based on both title and artist.[First title-first artist and second title-second aritst].*
My Source XML is Like Following::
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
<cd>
<title>Burlesque</title>
<title>Empire</title>
<title>Emp</title>
<title>Em</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your</title>
<title>heart</title>
<artist>Bonnie</artist>
<artist> Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title/>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
</catalog>
XSLT ::
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes"/>
<xsl:key name="k" match="title" use="text()"/>
<xsl:key name="l" match="artist" use="text()"/>
<xsl:template match="/">
<catalog>
<xsl:apply-templates select="//cd/title | artist[not(node() = preceding-sibling::node())]"/>
</catalog>
</xsl:template>
<xsl:template match="//cd">
<xsl:param name="title" select="title"/>
<xsl:param name="artist" select="artist"/>
<cd>
<xsl:copy-of select="key('k', $title)[not(node() = preceding-sibling::node())]"/>
<xsl:copy-of select="key('l', $artist)[not(node() = preceding-sibling::node())]"/>
<xsl:copy-of select="./*[name() != 'title' and 'artist']"/>
</cd>
</xsl:template>
<xsl:template match="title">
<xsl:apply-templates select="..">
<xsl:with-param name="title" select="."/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
What i am getting ::
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<cd>
<title>Burlesque</title>
<artist>Bob Dylan</artist>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Empire</title>
<artist>Bob Dylan</artist>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Emp</title>
<artist>Bob Dylan</artist>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Em</title>
<artist>Bob Dylan</artist>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your</title>
<artist>Bonnie</artist>
<artist> Tyler</artist>
<artist>Bonnie</artist>
<artist> Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>heart</title>
<artist>Bonnie</artist>
<artist> Tyler</artist>
<artist>Bonnie</artist>
<artist> Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<artist>Dolly Parton</artist>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
</catalog>
What I need ::
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<cd>
<title>Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Empire</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Emp</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Em</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your</title>
<artist>Bonnie</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>heart</title>
<artist> Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<artist>Dolly Parton</artist>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
</catalog>
Can any one help me in this ???
This is an application of a “generic XML shredding” transformation, where the parameter is set to the wanted leaf nodes and a minor post-processing is done to remove two top wrapping nodes from the result and re-wrap:
when this transformation is applied on the provided XML document:
the wanted, correct result is produced:
Update: The OP has changed his question and he is asking that for CDs with more than one artist there should be an additional split by artist.
Here is the solution — it is a two-pass-processing. In the first pass the document is converted to a
catalogin which eachcdhas a singleartist. Then the second pass is the solution I already gave above:When this transformation is applied on the same XML document (above), the result now satisfies the additional requirements: