Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > Help on xslt - grouping

Reply
Thread Tools

Help on xslt - grouping

 
 
Per Jørgen Vigdal
Guest
Posts: n/a
 
      05-19-2005
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"
xmlnssl="http://www.w3.org/1999/XSL/Transform">
<xslutput method="xml" indent="yes"/>
<xslutput 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>


 
Reply With Quote
 
 
 
 
Dimitre Novatchev
Guest
Posts: n/a
 
      05-19-2005
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" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>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"
> xmlnssl="http://www.w3.org/1999/XSL/Transform">
> <xslutput method="xml" indent="yes"/>
> <xslutput 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>
>
>



 
Reply With Quote
 
 
 
 
Per Jørgen Vigdal
Guest
Posts: n/a
 
      05-19-2005
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"
xmlnssl="http://www.w3.org/1999/XSL/Transform">
<xslutput method="xml" indent="yes"/>
<xslutput 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" <(E-Mail Removed)> wrote in message
news:428cf388$0$73807$(E-Mail Removed) eenews.net...
> 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" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> >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"
> > xmlnssl="http://www.w3.org/1999/XSL/Transform">
> > <xslutput method="xml" indent="yes"/>
> > <xslutput 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>
> >
> >

>
>



 
Reply With Quote
 
Volkm@r
Guest
Posts: n/a
 
      05-20-2005
Per Jørgen Vigdal wrote:
> 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"
> xmlnssl="http://www.w3.org/1999/XSL/Transform">
> <xslutput method="xml" indent="yes"/>
> <xslutput 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>
>
>


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 - ........./>
 
Reply With Quote
 
Dimitre Novatchev
Guest
Posts: n/a
 
      05-20-2005

"Per Jørgen Vigdal" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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>



This transformation:

<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">
<xslutput 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


 
Reply With Quote
 
Per Jørgen Vigdal
Guest
Posts: n/a
 
      05-20-2005
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" <(E-Mail Removed)> wrote in message
news:428db6ed$0$75094$(E-Mail Removed) eenews.net...
>
> "Per Jørgen Vigdal" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > 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>

>
>
> This transformation:
>
> <xsl:stylesheet version="1.0"
> xmlnssl="http://www.w3.org/1999/XSL/Transform">
> <xslutput 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
>
>



 
Reply With Quote
 
Dimitre Novatchev
Guest
Posts: n/a
 
      05-20-2005

"Per Jørgen Vigdal" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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


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


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
XSLT Grouping please help Mark XML 1 08-18-2005 08:28 PM
Transforming with XSLT, Grouping elements until difference found. Jody Greening XML 5 01-06-2005 06:52 PM
Help Grouping/Counting XSLT Graham XML 3 09-17-2004 06:20 PM
XSLT XML-HTML Transformation using grouping Kevin Brown XML 3 08-28-2004 03:39 PM
XSLT: sorting and grouping Christian Ludwig XML 2 11-26-2003 10:37 AM



Advertisments