Connecting Tech Pros Worldwide Forums | Help | Site Map

Help on xslt - grouping

Per Jørgen Vigdal
Guest
 
Posts: n/a
#1: Jul 20 '05
I have a XML that I need to map.
The XML goes like:

<Children>
<Child>
<References>
<External>
<Reference name="filename" value="1.dat"/>
<Reference name="invoicenr" value="1111111"/>
<Reference name="invoicer_name" value="Bill"/>
<Reference name="invoiceref" value="bbbbbb"/>
</External>
</References>
</Child>
<Child>
<References>
<External>
<Reference name="filename" value="2.dat"/>
<Reference name="invoicenr" value="222222"/>
<Reference name="invoicer_name" value="Bill"/>
<Reference name="invoiceref" value="bbbbbb"/>
</External>
</References>
</Child>
<Child>
<References>
<External>
<Reference name="filename" value="3.dat"/>
<Reference name="invoicenr" value="33333"/>
<Reference name="invoicer_name" value="Clinton"/>
<Reference name="invoiceref" value="ccccc"/>
</External>
</References>
</Child>
</Children>

I want the structure to map to:

<Senders>
<Sender>
<invoicer_name>Bill</invoicer_name>
<invoiceref>bbbbbb</invoiceref>
<Items TotalItems="2"/>
</Sender>
<Sender>
<invoicer_name>Clinton</invoicer_name>
<invoiceref>ccccc</invoiceref>
<Items TotalItems="1"/>
</Sender>
</Senders>

I have tried to use the "Muenchian Grouping" method, but am not able to
obtain both
<invoicer_name> and <invoiceref> under the <Sender> tag

Here is my xsl :

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:output encoding="ISO-8859-1"/>
<xsl:key name="kDistinctSender"
match="Children/Child/References/External/Reference[@name='invoicer_name']/@
value" use="."/>
<xsl:template match="/">
<Senders>
<!-- go through distinct InvoicerName -->
<xsl:for-each
select="/Children/Child/References/External/Reference[@name='invoicer_name']
/@value[generate-id()=generate-id(key('kDistinctSender',.))]">
<!-- sort by InvoicerName -->
<xsl:sort select="."/>
<Sender>
<xsl:variable name="InvoicerName">
<xsl:value-of select="."/>
</xsl:variable>
<InvoicerName>
<xsl:value-of select="$InvoicerName"/>
</InvoicerName>
<Items TotalItems="{count(key('kDistinctSender',.))}">
</Items>
</Sender>
</xsl:for-each>
</Senders>
</xsl:template>
</xsl:stylesheet>



Dimitre Novatchev
Guest
 
Posts: n/a
#2: Jul 20 '05

re: Help on xslt - grouping


Specify for the "use" attribute of xsl:key the concatenation of the values
of "invoicer_name" and "invoiceref".


Cheers,
Dimitre Novatchev


"Per Jørgen Vigdal" <per.jorgen.vigdal@ergo.no> wrote in message
news:1116520924.104290@makrell.interpost.no...[color=blue]
>I have a XML that I need to map.
> The XML goes like:
>
> <Children>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="1.dat"/>
> <Reference name="invoicenr" value="1111111"/>
> <Reference name="invoicer_name" value="Bill"/>
> <Reference name="invoiceref" value="bbbbbb"/>
> </External>
> </References>
> </Child>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="2.dat"/>
> <Reference name="invoicenr" value="222222"/>
> <Reference name="invoicer_name" value="Bill"/>
> <Reference name="invoiceref" value="bbbbbb"/>
> </External>
> </References>
> </Child>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="3.dat"/>
> <Reference name="invoicenr" value="33333"/>
> <Reference name="invoicer_name" value="Clinton"/>
> <Reference name="invoiceref" value="ccccc"/>
> </External>
> </References>
> </Child>
> </Children>
>
> I want the structure to map to:
>
> <Senders>
> <Sender>
> <invoicer_name>Bill</invoicer_name>
> <invoiceref>bbbbbb</invoiceref>
> <Items TotalItems="2"/>
> </Sender>
> <Sender>
> <invoicer_name>Clinton</invoicer_name>
> <invoiceref>ccccc</invoiceref>
> <Items TotalItems="1"/>
> </Sender>
> </Senders>
>
> I have tried to use the "Muenchian Grouping" method, but am not able to
> obtain both
> <invoicer_name> and <invoiceref> under the <Sender> tag
>
> Here is my xsl :
>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:output method="xml" indent="yes"/>
> <xsl:output encoding="ISO-8859-1"/>
> <xsl:key name="kDistinctSender"
> match="Children/Child/References/External/Reference[@name='invoicer_name']/@
> value" use="."/>
> <xsl:template match="/">
> <Senders>
> <!-- go through distinct InvoicerName -->
> <xsl:for-each
> select="/Children/Child/References/External/Reference[@name='invoicer_name']
> /@value[generate-id()=generate-id(key('kDistinctSender',.))]">
> <!-- sort by InvoicerName -->
> <xsl:sort select="."/>
> <Sender>
> <xsl:variable name="InvoicerName">
> <xsl:value-of select="."/>
> </xsl:variable>
> <InvoicerName>
> <xsl:value-of select="$InvoicerName"/>
> </InvoicerName>
> <Items TotalItems="{count(key('kDistinctSender',.))}">
> </Items>
> </Sender>
> </xsl:for-each>
> </Senders>
> </xsl:template>
> </xsl:stylesheet>
>
>[/color]


Per Jørgen Vigdal
Guest
 
Posts: n/a
#3: Jul 20 '05

re: Help on xslt - grouping


Thanks
I have tried to play around with concatenation and cant get it right, her is
the result :

<Senders>
<Sender>
<InvoicerName>Bill</InvoicerName>
<Items TotalItems="3"/>
</Sender>
</Senders>


Using xsl :

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:output encoding="ISO-8859-1"/>
<xsl:key name="kDistinctSender"
match="Children/Child/References/External/Reference[@name='invoicer_name']/@
value" use="concat(@name,'||',@value)"/>
<xsl:template match="/">
<Senders>

<xsl:for-each
select="/Children/Child/References/External/Reference[@name='invoicer_name']
/@value[generate-id()=generate-id(key('kDistinctSender',concat(@name,'||',@v
alue)))]">

<xsl:sort select="."/>
<Sender>
<xsl:variable name="InvoicerName">
<xsl:value-of select="."/>
</xsl:variable>
<InvoicerName>
<xsl:value-of select="$InvoicerName"/>
</InvoicerName>
<Items
TotalItems="{count(key('kDistinctSender',concat(@n ame,'||',@value)))}">
</Items>
</Sender>
</xsl:for-each>
</Senders>
</xsl:template>
</xsl:stylesheet>
"Dimitre Novatchev" <dimitren@tpg.com.au> wrote in message
news:428cf388$0$73807$892e7fe2@authen.white.readfr eenews.net...[color=blue]
> Specify for the "use" attribute of xsl:key the concatenation of the values
> of "invoicer_name" and "invoiceref".
>
>
> Cheers,
> Dimitre Novatchev
>
>
> "Per Jørgen Vigdal" <per.jorgen.vigdal@ergo.no> wrote in message
> news:1116520924.104290@makrell.interpost.no...[color=green]
> >I have a XML that I need to map.
> > The XML goes like:
> >
> > <Children>
> > <Child>
> > <References>
> > <External>
> > <Reference name="filename" value="1.dat"/>
> > <Reference name="invoicenr" value="1111111"/>
> > <Reference name="invoicer_name" value="Bill"/>
> > <Reference name="invoiceref" value="bbbbbb"/>
> > </External>
> > </References>
> > </Child>
> > <Child>
> > <References>
> > <External>
> > <Reference name="filename" value="2.dat"/>
> > <Reference name="invoicenr" value="222222"/>
> > <Reference name="invoicer_name" value="Bill"/>
> > <Reference name="invoiceref" value="bbbbbb"/>
> > </External>
> > </References>
> > </Child>
> > <Child>
> > <References>
> > <External>
> > <Reference name="filename" value="3.dat"/>
> > <Reference name="invoicenr" value="33333"/>
> > <Reference name="invoicer_name" value="Clinton"/>
> > <Reference name="invoiceref" value="ccccc"/>
> > </External>
> > </References>
> > </Child>
> > </Children>
> >
> > I want the structure to map to:
> >
> > <Senders>
> > <Sender>
> > <invoicer_name>Bill</invoicer_name>
> > <invoiceref>bbbbbb</invoiceref>
> > <Items TotalItems="2"/>
> > </Sender>
> > <Sender>
> > <invoicer_name>Clinton</invoicer_name>
> > <invoiceref>ccccc</invoiceref>
> > <Items TotalItems="1"/>
> > </Sender>
> > </Senders>
> >
> > I have tried to use the "Muenchian Grouping" method, but am not able to
> > obtain both
> > <invoicer_name> and <invoiceref> under the <Sender> tag
> >
> > Here is my xsl :
> >
> > <xsl:stylesheet version="1.0"
> > xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> > <xsl:output method="xml" indent="yes"/>
> > <xsl:output encoding="ISO-8859-1"/>
> > <xsl:key name="kDistinctSender"
> >[/color][/color]
match="Children/Child/References/External/Reference[@name='invoicer_name']/@[color=blue][color=green]
> > value" use="."/>
> > <xsl:template match="/">
> > <Senders>
> > <!-- go through distinct InvoicerName -->
> > <xsl:for-each
> >[/color][/color]
select="/Children/Child/References/External/Reference[@name='invoicer_name'][color=blue][color=green]
> > /@value[generate-id()=generate-id(key('kDistinctSender',.))]">
> > <!-- sort by InvoicerName -->
> > <xsl:sort select="."/>
> > <Sender>
> > <xsl:variable name="InvoicerName">
> > <xsl:value-of select="."/>
> > </xsl:variable>
> > <InvoicerName>
> > <xsl:value-of select="$InvoicerName"/>
> > </InvoicerName>
> > <Items TotalItems="{count(key('kDistinctSender',.))}">
> > </Items>
> > </Sender>
> > </xsl:for-each>
> > </Senders>
> > </xsl:template>
> > </xsl:stylesheet>
> >
> >[/color]
>
>[/color]


Volkm@r
Guest
 
Posts: n/a
#4: Jul 20 '05

re: Help on xslt - grouping


Per Jørgen Vigdal wrote:[color=blue]
> I have a XML that I need to map.
> The XML goes like:
>
> <Children>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="1.dat"/>
> <Reference name="invoicenr" value="1111111"/>
> <Reference name="invoicer_name" value="Bill"/>
> <Reference name="invoiceref" value="bbbbbb"/>
> </External>
> </References>
> </Child>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="2.dat"/>
> <Reference name="invoicenr" value="222222"/>
> <Reference name="invoicer_name" value="Bill"/>
> <Reference name="invoiceref" value="bbbbbb"/>
> </External>
> </References>
> </Child>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="3.dat"/>
> <Reference name="invoicenr" value="33333"/>
> <Reference name="invoicer_name" value="Clinton"/>
> <Reference name="invoiceref" value="ccccc"/>
> </External>
> </References>
> </Child>
> </Children>
>
> I want the structure to map to:
>
> <Senders>
> <Sender>
> <invoicer_name>Bill</invoicer_name>
> <invoiceref>bbbbbb</invoiceref>
> <Items TotalItems="2"/>
> </Sender>
> <Sender>
> <invoicer_name>Clinton</invoicer_name>
> <invoiceref>ccccc</invoiceref>
> <Items TotalItems="1"/>
> </Sender>
> </Senders>
>
> I have tried to use the "Muenchian Grouping" method, but am not able to
> obtain both
> <invoicer_name> and <invoiceref> under the <Sender> tag
>
> Here is my xsl :
>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:output method="xml" indent="yes"/>
> <xsl:output encoding="ISO-8859-1"/>
> <xsl:key name="kDistinctSender"
> match="Children/Child/References/External/Reference[@name='invoicer_name']/@
> value" use="."/>
> <xsl:template match="/">
> <Senders>
> <!-- go through distinct InvoicerName -->
> <xsl:for-each
> select="/Children/Child/References/External/Reference[@name='invoicer_name']
> /@value[generate-id()=generate-id(key('kDistinctSender',.))]">
> <!-- sort by InvoicerName -->
> <xsl:sort select="."/>
> <Sender>
> <xsl:variable name="InvoicerName">
> <xsl:value-of select="."/>
> </xsl:variable>
> <InvoicerName>
> <xsl:value-of select="$InvoicerName"/>
> </InvoicerName>
> <Items TotalItems="{count(key('kDistinctSender',.))}">
> </Items>
> </Sender>
> </xsl:for-each>
> </Senders>
> </xsl:template>
> </xsl:stylesheet>
>
>[/color]

Did you try to simply put them in the right order?


<xsl:template match="/">
<Senders>
<!-- go through distinct InvoicerName -->
<xsl:apply-templates select="-XPath expression-">
</Senders>
</xsl:template>

<xsl:template match="-expression from above-">
<Sender>
<xsl:apply-templates select=".[@name='invoicer_name']"/>
<xsl:apply-templates select=".[@name='invoiceref']"/>
<xsl:apply-templates select=".[@name='otherArtributeName']"/>
<xsl:apply-templates select=".[@name='............']"/>
<xsl:apply-templates select=".[@name='-one more line-']"/>
</Sender>
</xsl:apply-templates>
</xsl:template>

<xsl:........... - And Some More Templates - ........./>
Dimitre Novatchev
Guest
 
Posts: n/a
#5: Jul 20 '05

re: Help on xslt - grouping



"Per Jørgen Vigdal" <per.jorgen.vigdal@ergo.no> wrote in message
news:1116535669.557231@makrell.interpost.no...[color=blue]
> Thanks
> I have tried to play around with concatenation and cant get it right, her
> is
> the result :
>
> <Senders>
> <Sender>
> <InvoicerName>Bill</InvoicerName>
> <Items TotalItems="3"/>
> </Sender>
> </Senders>[/color]


This transformation:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:strip-space elements="*"/>

<xsl:key name="kExtNameRef" match="External"
use="concat(Reference[@name='invoicer_name']/@value,
'+',
Reference[@name='invoiceref']/@value
)"/>
<xsl:template match="/">
<Senders>
<xsl:for-each select=
"/*/*/*/External
[generate-id()
=
generate-id(
key('kExtNameRef',
concat(Reference[@name='invoicer_name']/@value,
'+',
Reference[@name='invoiceref']/@value
)
)[1]
)
]">
<Sender>
<invoicer_name>
<xsl:value-of select=
"Reference[@name='invoicer_name']/@value"/>
</invoicer_name>
<invoiceref>
<xsl:value-of select=
"Reference[@name='invoiceref']/@value"/>
</invoiceref>
<Items TotalItems="{
count(
key('kExtNameRef',
concat(Reference[@name='invoicer_name']/@value,
'+',
Reference[@name='invoiceref']/@value
)
)
)
}"/>
</Sender>
</xsl:for-each>
</Senders>

</xsl:template>
</xsl:stylesheet>

when applied on your source.xml:

<Children>
<Child>
<References>
<External>
<Reference name="filename" value="1.dat"/>
<Reference name="invoicenr" value="1111111"/>
<Reference name="invoicer_name" value="Bill"/>
<Reference name="invoiceref" value="bbbbbb"/>
</External>
</References>
</Child>
<Child>
<References>
<External>
<Reference name="filename" value="2.dat"/>
<Reference name="invoicenr" value="222222"/>
<Reference name="invoicer_name" value="Bill"/>
<Reference name="invoiceref" value="bbbbbb"/>
</External>
</References>
</Child>
<Child>
<References>
<External>
<Reference name="filename" value="3.dat"/>
<Reference name="invoicenr" value="33333"/>
<Reference name="invoicer_name" value="Clinton"/>
<Reference name="invoiceref" value="ccccc"/>
</External>
</References>
</Child>
</Children>

produces the wanted result:

<Senders>
<Sender>
<invoicer_name>Bill</invoicer_name>
<invoiceref>bbbbbb</invoiceref>
<Items TotalItems="2" />
</Sender>
<Sender>
<invoicer_name>Clinton</invoicer_name>
<invoiceref>ccccc</invoiceref>
<Items TotalItems="1" />
</Sender>
</Senders>


Hope this helped.

Cheers,
Dimitre Novatchev


Per Jørgen Vigdal
Guest
 
Posts: n/a
#6: Jul 20 '05

re: Help on xslt - grouping


This is great, exactly what I want. Thank you.
This is goanna be tested in QA 22. Mai and if successful, put into
production on 25. Mai where the
xsl will do transformation on files that are as big as 100MB with thousands
of items






"Dimitre Novatchev" <dimitren@tpg.com.au> wrote in message
news:428db6ed$0$75094$892e7fe2@authen.white.readfr eenews.net...[color=blue]
>
> "Per Jørgen Vigdal" <per.jorgen.vigdal@ergo.no> wrote in message
> news:1116535669.557231@makrell.interpost.no...[color=green]
> > Thanks
> > I have tried to play around with concatenation and cant get it right,[/color][/color]
her[color=blue][color=green]
> > is
> > the result :
> >
> > <Senders>
> > <Sender>
> > <InvoicerName>Bill</InvoicerName>
> > <Items TotalItems="3"/>
> > </Sender>
> > </Senders>[/color]
>
>
> This transformation:
>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:output omit-xml-declaration="yes" indent="yes"/>
>
> <xsl:strip-space elements="*"/>
>
> <xsl:key name="kExtNameRef" match="External"
> use="concat(Reference[@name='invoicer_name']/@value,
> '+',
> Reference[@name='invoiceref']/@value
> )"/>
> <xsl:template match="/">
> <Senders>
> <xsl:for-each select=
> "/*/*/*/External
> [generate-id()
> =
> generate-id(
> key('kExtNameRef',
> concat(Reference[@name='invoicer_name']/@value,
> '+',
> Reference[@name='invoiceref']/@value
> )
> )[1]
> )
> ]">
> <Sender>
> <invoicer_name>
> <xsl:value-of select=
> "Reference[@name='invoicer_name']/@value"/>
> </invoicer_name>
> <invoiceref>
> <xsl:value-of select=
> "Reference[@name='invoiceref']/@value"/>
> </invoiceref>
> <Items TotalItems="{
> count(
> key('kExtNameRef',
> concat(Reference[@name='invoicer_name']/@value,
> '+',
> Reference[@name='invoiceref']/@value
> )
> )
> )
> }"/>
> </Sender>
> </xsl:for-each>
> </Senders>
>
> </xsl:template>
> </xsl:stylesheet>
>
> when applied on your source.xml:
>
> <Children>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="1.dat"/>
> <Reference name="invoicenr" value="1111111"/>
> <Reference name="invoicer_name" value="Bill"/>
> <Reference name="invoiceref" value="bbbbbb"/>
> </External>
> </References>
> </Child>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="2.dat"/>
> <Reference name="invoicenr" value="222222"/>
> <Reference name="invoicer_name" value="Bill"/>
> <Reference name="invoiceref" value="bbbbbb"/>
> </External>
> </References>
> </Child>
> <Child>
> <References>
> <External>
> <Reference name="filename" value="3.dat"/>
> <Reference name="invoicenr" value="33333"/>
> <Reference name="invoicer_name" value="Clinton"/>
> <Reference name="invoiceref" value="ccccc"/>
> </External>
> </References>
> </Child>
> </Children>
>
> produces the wanted result:
>
> <Senders>
> <Sender>
> <invoicer_name>Bill</invoicer_name>
> <invoiceref>bbbbbb</invoiceref>
> <Items TotalItems="2" />
> </Sender>
> <Sender>
> <invoicer_name>Clinton</invoicer_name>
> <invoiceref>ccccc</invoiceref>
> <Items TotalItems="1" />
> </Sender>
> </Senders>
>
>
> Hope this helped.
>
> Cheers,
> Dimitre Novatchev
>
>[/color]


Dimitre Novatchev
Guest
 
Posts: n/a
#7: Jul 20 '05

re: Help on xslt - grouping



"Per Jørgen Vigdal" <per.jorgen.vigdal@ergo.no> wrote in message
news:1116597174.198935@makrell.interpost.no...[color=blue]
> This is great, exactly what I want. Thank you.
> This is goanna be tested in QA 22. Mai and if successful, put into
> production on 25. Mai where the
> xsl will do transformation on files that are as big as 100MB with
> thousands
> of items[/color]

Good luck, and it would be interesting if you share your experience (or if
you have any problems -- just signal) to the newsgroups (and the xsl-list).


Cheers,
Dimitre Novatchev


Closed Thread