|
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 |