![]() |
![]() | ![]() | ![]() | Altova Mailing List Archives>Archive Index >microsoft.public.xsl Archive Home >Recent entries >Thread Prev - Join in XSLT : too many copies >Thread Next - Re: Join in XSLT : too many copies Re: Join in XSLT : too many copiesTo: NULL Date: 5/3/2004 6:25:00 PM Carota wrote: > I am trying to write a XSLT file to transform this XML: > > <?xml version="1.0" encoding="UTF-8"?><bib><book year="1999"><title>A title</title><author><last>Smith</last><first>John</first></author></book><book year="2003"><title>Another title</title><author><last>Lastname</last><first>Mark</first></author><author><last>Smith</last><first>John</first></author><author><last>Smith</last><first>Mary</first></author><author><last>Smith</last><first>Jack</first></author></book><book year="2003"><title>The third title</title><author><last>Smith</last><first>John</first></author><author><last>Doe</last><first>Paul</first></author></book></bib> > > > into this: > > <?xml version="1.0" encoding="UTF-8"?><bib><book year="2003"><title>Another title</title><author><last>Lastname</last><first>Mark</first></author><author><last>Smith</last><first>John</first></author><author><last>Smith</last><first>Mary</first></author><author><last>Smith</last><first>Jack</first></author></book></bib> > > ---------------------------------------------------------------------------------------- > The query I want to write is: > "copy all the books which have at least two authors with the same <last> but with different <first>" > The problem is that I can't obtain just a single copy for each book, but I obtain as many copy as the matching authors. > How can I solve this? Here is my attempt at that <?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" encoding="UTF-8" /> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()" /> </xsl:copy> </xsl:template> <xsl:template match="book"> <xsl:variable name="twoAuthors"> <xsl:call-template name="hasMatchingAuthors"> <xsl:with-param name="authors" select="author" /> </xsl:call-template> </xsl:variable> <xsl:if test="$twoAuthors = 'true'"> <xsl:copy-of select="." /> </xsl:if> </xsl:template> <xsl:template name="hasMatchingAuthors"> <xsl:param name="authors" /> <xsl:variable name="firstAuthor" select="$authors[1]" /> <xsl:variable name="otherAuthors" select="$authors[position() > 1]" /> <xsl:variable name="hasMatchingSiblings"> <xsl:call-template name="hasMatchingSiblings"> <xsl:with-param name="author" select="$firstAuthor" /> <xsl:with-param name="siblings" select="$otherAuthors" /> </xsl:call-template> </xsl:variable> <xsl:choose> <xsl:when test="not($otherAuthors)"><xsl:value-of select="'false'" /></xsl:when> <xsl:when test="$hasMatchingSiblings = 'true'"><xsl:value-of select="'true'" /></xsl:when> <xsl:otherwise> <xsl:call-template name="hasMatchingAuthors"> <xsl:with-param name="authors" select="$otherAuthors" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="hasMatchingSiblings"> <xsl:param name="author" /> <xsl:param name="siblings" /> <xsl:choose> <xsl:when test="not($siblings)"> <xsl:value-of select="'false'" /> </xsl:when> <xsl:when test="$author/last = $siblings[1]/last and $author/first != $siblings[1]/first"> <xsl:value-of select="'true'" /> </xsl:when> <xsl:otherwise> <xsl:call-template name="hasMatchingSiblings"> <xsl:with-param name="author" select="$author" /> <xsl:with-param name="siblings" select="$siblings[position() > 1]" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> it should give you the result you want I think. -- Martin Honnen http://JavaScript.FAQTs.com/ | ![]() | ![]() | ![]() |
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | |||||
|
