Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > Help working with distinct records in an xml doc

Reply
Thread Tools

Help working with distinct records in an xml doc

 
 
Chris Kettenbach
Guest
Posts: n/a
 
      08-24-2005
Good Morning,
Sorry for xposting. Just need a liitle help.
I have an xml file that's generated from a database. How do I select
distinct values from a field in xslt and then loop through the records and
produce output. Example

<registrations>
<registration>
<company>Awesome Printers</company>
<first>John</first>
<last>Smith</last>
</registration>
<registration>
<company>Awesome Printers</company>
<first>Bob</first>
<last>Roberts</last>
</registration>
<registration>
<company>Awesome Printers</company>
<first>John</first>
<last>Johnson</last>
</registration>
<registration>
<company>Other Company</company>
<first>Tom</first>
<last>Thomas</last>
</registration>
<registration>
<company>Other Company</company>
<first>Dan</first>
<last>Daniels</last>
</registration>
</registrations>
++++++++++++++++++++++++++++++++++++++++++++++++
I want the out put to be something like this

<table>
<tr>
<td>Company Name</td>
<td>Employees</td>
</tr>
<tr>
<td>Awesome Printers</td>
<td>John Smith<br/>
Bob Roberts<br/>
John Johnson<br/></td>
</tr>
<tr>
<td>Other Company</td>
<td>Tom Thomas<br/>
Dan Daniels<br/></td>
</tr>
</table>

Effectively writing unique company names once and then putting only the
employees from that company into the employee table cell.

Thanks for any advise.
Regards,
Chris



 
Reply With Quote
 
 
 
 
Peter Flynn
Guest
Posts: n/a
 
      08-24-2005
Chris Kettenbach wrote:

> Good Morning,
> Sorry for xposting. Just need a liitle help.
> I have an xml file that's generated from a database. How do I select
> distinct values from a field


XML doesn't have fields -- the database did but this isn't a database any
more. In XML they're called elements (they've got a lot in common with
fields but they ain't the same).

> in xslt and then loop through the records and
> produce output.


It looks like you need to process the information grouped by company name,
and there's a technique in XSLT 1.0 for doing this called Muenchian grouping
(it won't be needed in XSLT 2 because that has a built-in group-processing
command, but XSLT 2 is not a Recommendation yet).

Check the XSLT FAQ for "Muenchian" to find examples.

///Peter

[Group and followup corrected to comp.text.xml]

> Example
>
> <registrations>
> <registration>
> <company>Awesome Printers</company>
> <first>John</first>
> <last>Smith</last>
> </registration>
> <registration>
> <company>Awesome Printers</company>
> <first>Bob</first>
> <last>Roberts</last>
> </registration>
> <registration>
> <company>Awesome Printers</company>
> <first>John</first>
> <last>Johnson</last>
> </registration>
> <registration>
> <company>Other Company</company>
> <first>Tom</first>
> <last>Thomas</last>
> </registration>
> <registration>
> <company>Other Company</company>
> <first>Dan</first>
> <last>Daniels</last>
> </registration>
> </registrations>
> ++++++++++++++++++++++++++++++++++++++++++++++++
> I want the out put to be something like this
>
> <table>
> <tr>
> <td>Company Name</td>
> <td>Employees</td>
> </tr>
> <tr>
> <td>Awesome Printers</td>
> <td>John Smith<br/>
> Bob Roberts<br/>
> John Johnson<br/></td>
> </tr>
> <tr>
> <td>Other Company</td>
> <td>Tom Thomas<br/>
> Dan Daniels<br/></td>
> </tr>
> </table>
>
> Effectively writing unique company names once and then putting only the
> employees from that company into the employee table cell.


If you scrolled down this far then you've been rewarded

The trick is to use lookup keys to test the selected group of elements
against, in order to pick only the first ocurrence in each group; then
output the group header at that point; and only then go and process all the
elements in the group to extract the detail from each of them.

The syntax is tricky because it's very compact. It selects all registration
elements, but subjects each of them to the test that [the number of nodes in
the union of (the current node and the first node with the current company
value returned by the lookup) is equal to 1] -- in effect meaning they are
one and the same node, ie the first in their company name grouping. You'll
probably need to read that 3 or 4 times -- it took me a week to grok it.

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlnssl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xslutput method="html"/>

<xsl:key name="entry" match="registration" use="company"/>

<xsl:template match="/">
<html>
<head>
<title>Registrations</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="registrations">
<table>
<xsl:for-each select="registration[count(.|key('entry',company
[1])=1]">
<xsl:sort select="company"/>
<tr>
<th valign="top">
<xsl:value-of select="company"/>
</th>
<td valign="top">
<xsl:for-each select="key('entry',current()/company)">
<xsl:sort select="last"/>
<xsl:value-of select="first"/>
<xsl:text> </xsl:text>
<xsl:value-of select="last"/>
<xsl:if test="position()!=last()">
<br/>
</xsl:if>
</xsl:for-each>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>

</xsl:stylesheet>

///Peter

 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      08-24-2005
Peter Flynn <(E-Mail Removed)> writes:
>XML doesn't have fields -- the database did but this isn't a
>database any more. In XML they're called elements


Sometimes it might be appropriate to use attributes.

 
Reply With Quote
 
Chris Kettenbach
Guest
Posts: n/a
 
      08-24-2005
Hi Peter,
I get error when processing the stylesheet. It errors here.

<xsl:for-each select="registration[count(.|key('entry',company
[1])=1]">

specifically:

Expression does not return a DOM node.
registration[-->count(.|key('entry',company[1])=1]<--

Ideas?


Thanks,
Chris

"Peter Flynn" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Chris Kettenbach wrote:
>
>> Good Morning,
>> Sorry for xposting. Just need a liitle help.
>> I have an xml file that's generated from a database. How do I select
>> distinct values from a field

>
> XML doesn't have fields -- the database did but this isn't a database any
> more. In XML they're called elements (they've got a lot in common with
> fields but they ain't the same).
>
>> in xslt and then loop through the records and
>> produce output.

>
> It looks like you need to process the information grouped by company name,
> and there's a technique in XSLT 1.0 for doing this called Muenchian
> grouping
> (it won't be needed in XSLT 2 because that has a built-in group-processing
> command, but XSLT 2 is not a Recommendation yet).
>
> Check the XSLT FAQ for "Muenchian" to find examples.
>
> ///Peter
>
> [Group and followup corrected to comp.text.xml]
>
>> Example
>>
>> <registrations>
>> <registration>
>> <company>Awesome Printers</company>
>> <first>John</first>
>> <last>Smith</last>
>> </registration>
>> <registration>
>> <company>Awesome Printers</company>
>> <first>Bob</first>
>> <last>Roberts</last>
>> </registration>
>> <registration>
>> <company>Awesome Printers</company>
>> <first>John</first>
>> <last>Johnson</last>
>> </registration>
>> <registration>
>> <company>Other Company</company>
>> <first>Tom</first>
>> <last>Thomas</last>
>> </registration>
>> <registration>
>> <company>Other Company</company>
>> <first>Dan</first>
>> <last>Daniels</last>
>> </registration>
>> </registrations>
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>> I want the out put to be something like this
>>
>> <table>
>> <tr>
>> <td>Company Name</td>
>> <td>Employees</td>
>> </tr>
>> <tr>
>> <td>Awesome Printers</td>
>> <td>John Smith<br/>
>> Bob Roberts<br/>
>> John Johnson<br/></td>
>> </tr>
>> <tr>
>> <td>Other Company</td>
>> <td>Tom Thomas<br/>
>> Dan Daniels<br/></td>
>> </tr>
>> </table>
>>
>> Effectively writing unique company names once and then putting only the
>> employees from that company into the employee table cell.

>
> If you scrolled down this far then you've been rewarded
>
> The trick is to use lookup keys to test the selected group of elements
> against, in order to pick only the first ocurrence in each group; then
> output the group header at that point; and only then go and process all
> the
> elements in the group to extract the detail from each of them.
>
> The syntax is tricky because it's very compact. It selects all
> registration
> elements, but subjects each of them to the test that [the number of nodes
> in
> the union of (the current node and the first node with the current company
> value returned by the lookup) is equal to 1] -- in effect meaning they are
> one and the same node, ie the first in their company name grouping. You'll
> probably need to read that 3 or 4 times -- it took me a week to grok it.
>
> <?xml version="1.0" encoding="iso-8859-1"?>
> <xsl:stylesheet xmlnssl="http://www.w3.org/1999/XSL/Transform"
> version="1.0">
>
> <xslutput method="html"/>
>
> <xsl:key name="entry" match="registration" use="company"/>
>
> <xsl:template match="/">
> <html>
> <head>
> <title>Registrations</title>
> </head>
> <body>
> <xsl:apply-templates/>
> </body>
> </html>
> </xsl:template>
>
> <xsl:template match="registrations">
> <table>
> <xsl:for-each select="registration[count(.|key('entry',company
> [1])=1]">
> <xsl:sort select="company"/>
> <tr>
> <th valign="top">
> <xsl:value-of select="company"/>
> </th>
> <td valign="top">
> <xsl:for-each select="key('entry',current()/company)">
> <xsl:sort select="last"/>
> <xsl:value-of select="first"/>
> <xsl:text> </xsl:text>
> <xsl:value-of select="last"/>
> <xsl:if test="position()!=last()">
> <br/>
> </xsl:if>
> </xsl:for-each>
> </td>
> </tr>
> </xsl:for-each>
> </table>
> </xsl:template>
>
> </xsl:stylesheet>
>
> ///Peter
>



 
Reply With Quote
 
toudidel
Guest
Posts: n/a
 
      08-25-2005
hint: from performed elements you have to create attributtes in yor new
element, because there isn't posibility to being few the same attributtes in
one xml element

td


 
Reply With Quote
 
Peter Flynn
Guest
Posts: n/a
 
      08-25-2005
Chris Kettenbach wrote:

> Hi Peter,
> I get error when processing the stylesheet. It errors here.
>
> <xsl:for-each select="registration[count(.|key('entry',company
> [1])=1]">
>
> specifically:
>
> Expression does not return a DOM node.
> registration[-->count(.|key('entry',company[1])=1]<--
>
> Ideas?


What processor are you using? I ran it through Saxon without errors, and the
output was:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Registrations</title>
</head>
<body>
<table>
<tr>
<th valign="top">Awesome Printers</th>
<td valign="top">John Johnson<br>Bob Roberts<br>John Smith
</td>
</tr>
<tr>
<th valign="top">Other Company</th>
<td valign="top">Dan Daniels<br>Tom Thomas
</td>
</tr>
</table>
</body>
</html>

///Peter

> "Peter Flynn" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> Chris Kettenbach wrote:
>>
>>> Good Morning,
>>> Sorry for xposting. Just need a liitle help.
>>> I have an xml file that's generated from a database. How do I select
>>> distinct values from a field

>>
>> XML doesn't have fields -- the database did but this isn't a database any
>> more. In XML they're called elements (they've got a lot in common with
>> fields but they ain't the same).
>>
>>> in xslt and then loop through the records and
>>> produce output.

>>
>> It looks like you need to process the information grouped by company
>> name, and there's a technique in XSLT 1.0 for doing this called Muenchian
>> grouping
>> (it won't be needed in XSLT 2 because that has a built-in
>> group-processing command, but XSLT 2 is not a Recommendation yet).
>>
>> Check the XSLT FAQ for "Muenchian" to find examples.
>>
>> ///Peter
>>
>> [Group and followup corrected to comp.text.xml]
>>
>>> Example
>>>
>>> <registrations>
>>> <registration>
>>> <company>Awesome Printers</company>
>>> <first>John</first>
>>> <last>Smith</last>
>>> </registration>
>>> <registration>
>>> <company>Awesome Printers</company>
>>> <first>Bob</first>
>>> <last>Roberts</last>
>>> </registration>
>>> <registration>
>>> <company>Awesome Printers</company>
>>> <first>John</first>
>>> <last>Johnson</last>
>>> </registration>
>>> <registration>
>>> <company>Other Company</company>
>>> <first>Tom</first>
>>> <last>Thomas</last>
>>> </registration>
>>> <registration>
>>> <company>Other Company</company>
>>> <first>Dan</first>
>>> <last>Daniels</last>
>>> </registration>
>>> </registrations>
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>> I want the out put to be something like this
>>>
>>> <table>
>>> <tr>
>>> <td>Company Name</td>
>>> <td>Employees</td>
>>> </tr>
>>> <tr>
>>> <td>Awesome Printers</td>
>>> <td>John Smith<br/>
>>> Bob Roberts<br/>
>>> John Johnson<br/></td>
>>> </tr>
>>> <tr>
>>> <td>Other Company</td>
>>> <td>Tom Thomas<br/>
>>> Dan Daniels<br/></td>
>>> </tr>
>>> </table>
>>>
>>> Effectively writing unique company names once and then putting only the
>>> employees from that company into the employee table cell.

>>
>> If you scrolled down this far then you've been rewarded
>>
>> The trick is to use lookup keys to test the selected group of elements
>> against, in order to pick only the first ocurrence in each group; then
>> output the group header at that point; and only then go and process all
>> the
>> elements in the group to extract the detail from each of them.
>>
>> The syntax is tricky because it's very compact. It selects all
>> registration
>> elements, but subjects each of them to the test that [the number of nodes
>> in
>> the union of (the current node and the first node with the current
>> company value returned by the lookup) is equal to 1] -- in effect meaning
>> they are one and the same node, ie the first in their company name
>> grouping. You'll probably need to read that 3 or 4 times -- it took me a
>> week to grok it.
>>
>> <?xml version="1.0" encoding="iso-8859-1"?>
>> <xsl:stylesheet xmlnssl="http://www.w3.org/1999/XSL/Transform"
>> version="1.0">
>>
>> <xslutput method="html"/>
>>
>> <xsl:key name="entry" match="registration" use="company"/>
>>
>> <xsl:template match="/">
>> <html>
>> <head>
>> <title>Registrations</title>
>> </head>
>> <body>
>> <xsl:apply-templates/>
>> </body>
>> </html>
>> </xsl:template>
>>
>> <xsl:template match="registrations">
>> <table>
>> <xsl:for-each select="registration[count(.|key('entry',company
>> [1])=1]">
>> <xsl:sort select="company"/>
>> <tr>
>> <th valign="top">
>> <xsl:value-of select="company"/>
>> </th>
>> <td valign="top">
>> <xsl:for-each select="key('entry',current()/company)">
>> <xsl:sort select="last"/>
>> <xsl:value-of select="first"/>
>> <xsl:text> </xsl:text>
>> <xsl:value-of select="last"/>
>> <xsl:if test="position()!=last()">
>> <br/>
>> </xsl:if>
>> </xsl:for-each>
>> </td>
>> </tr>
>> </xsl:for-each>
>> </table>
>> </xsl:template>
>>
>> </xsl:stylesheet>
>>
>> ///Peter
>>


 
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
number of distinct elements in a const container and iterating over the distinct elements Hicham Mouline C++ 1 04-11-2010 10:56 AM
NEWBIE Q:Selecting Distinct records from a datasource AlecL ASP .Net 1 03-08-2007 04:53 PM
String[] files = {"a.doc, b.doc"}; VERSUS String[] files = new String[] {"a.doc, b.doc"}; Matt Java 3 09-17-2004 10:28 PM
XML Distinct Yogs ASP .Net 3 02-16-2004 07:12 AM
How do I filter records from XML doc? jj23 XML 1 02-13-2004 09:28 PM



Advertisments