Subject: Re: [xsl] How to merge XML node including all the corresponding children with unique element and latest value? From: Lucent Lau <lucent.lau@xxxxxxxxx> Date: Wed, 18 Jul 2012 02:22:02 +0700 |
Here is my code. <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:tn="http://" exclude-result-prefixes="xsl xs fn tn"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <xsl:template match="genre/*"> <xsl:copy> <xsl:apply-templates select="@*" /> <xsl:apply-templates select=" book[@id=current()/@id][@action='extend'] [not( preceding-sibling::book[@id=current()/@id][@action='borrow'])]" /> <xsl:for-each-group select="book[@id=current()/@id][@action='borrow'] | book[@id=current()/@id][@action='extend'] [preceding-sibling::book[@id=current()/@id][@action='borrow']]" group-starting-with="book[@action='borrow']"> <xsl:for-each select="current-group()[1]"> <xsl:copy> <xsl:apply-templates select="@*" /> <xsl:call-template name="merge-books-deeply"> <xsl:with-param name="books" select="current-group()" /> <xsl:with-param name="name-path" select="()" /> </xsl:call-template> </xsl:copy> </xsl:for-each> </xsl:for-each-group> <xsl:apply-templates select=" node()[ not( self::book[@id=current()/@id][@action=('borrow','extend')])]" /> </xsl:copy> </xsl:template> <xsl:function name="tn:children-on-path" as="element()*"> <xsl:param name="base" as="element()*" /> <xsl:param name="path" as="xs:string*" /> <xsl:choose> <xsl:when test="fn:empty($base)"> <xsl:sequence select="()" /> </xsl:when> <xsl:when test="fn:empty($path)"> <xsl:copy-of select="$base/*" /> </xsl:when> <xsl:otherwise> <xsl:sequence select="tn:children-on-path( $base/*[name()=$path[1]], $path[position() ne 1])" /> </xsl:otherwise> </xsl:choose> </xsl:function> <xsl:template name="merge-books-deeply"> <xsl:param name="books" as="element()*" /> <xsl:param name="name-path" as="xs:string*" /> <xsl:for-each-group select="tn:children-on-path($books,$name-path)" group-by="name()"> <xsl:for-each select="current-group()[last()]" > <xsl:copy> <xsl:apply-templates select="@*" /> <xsl:call-template name="merge-books-deeply"> <xsl:with-param name="books" select="$books" /> <xsl:with-param name="name-path" select="$name-path,name()" /> </xsl:call-template> <xsl:apply-templates select="text()" /> </xsl:copy> </xsl:for-each> </xsl:for-each-group> </xsl:template> </xsl:stylesheet> The problem is that if i change all the book id to '1a' the code wont work, could you point me to the right direction? Thanks On Tue, Jul 17, 2012 at 2:42 PM, Michel Hendriksen <michel.hendriksen@xxxxx> wrote: > Can;'t you try first? > > On Mon, Jul 16, 2012 at 6:54 PM, Lucent Lau <lucent.lau@xxxxxxxxx> wrote: >> I have this XSL: >> <root> >> <library id="L1"> >> <floor1 id="1"> >> <shelf id="1"> >> <book id="1" action="borrow"> >> <attributes> >> <user>John</user> >> </attributes> >> <other1>y</other1> >> </book> >> <book id="1" action="extend"> >> <attributes> >> <user>Woo</user> >> <length>3</length> >> </attributes> >> <other2>y</other2> >> </book> >> <book id="2" action="extend"> >> <attributes> >> <length>2</length> >> <condition>ok</condition> >> </attributes> >> <other3>y</other3> >> </book> >> </shelf> >> <shelf id="2"> >> </floor1> >> <floor1 id="2">..</floor1> >> </library> >> </root> >> >> Output: >> <root> >> <library id="L1"> >> <floor1 id="1"> >> <shelf id="1"> >> <book id="1" action="borrow"> >> <attributes> >> <user>Woo</user> >> <length>3</length> >> </attributes> >> <other1>y</other1> >> <other2>y</other2> >> </book> >> >> <book id="2" action="extend"> >> <attributes> >> <length>2</length> >> <condition>ok</condition> >> </attributes> >> <other3>y</other3> >> </book> >> </shelf> >> <shelf id="2"> >> </floor1> >> <floor1 id="2">..</floor1> >> </library> >> </root> >> >> I need to combine the node such that For every node that has the same >> id with action=borrow followed by one or more node with action=extend >> >> Merge it together to the node with action=borrow. >> Merge the attributes children together such that it will have all >> the unique attributes from the siblings with the latest value. >> leave other children unchanged >> >> Please let me know how to fix this transformation using XSLT 2.0 ? >> >> Thanks very much. >> LL
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] How to merge XML node inc, Michel Hendriksen | Thread | [xsl] tokenize() and regex-group ?, Matthieu Ricaud-Duss |
Re: [xsl] XSLT extension for readin, Martynas Jusevičius | Date | Re: [xsl] XSLT extension for readin, David Carlisle |
Month |