Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > Selecting unique combinations from two node sets

Reply
Thread Tools

Selecting unique combinations from two node sets

 
 
johkar
Guest
Posts: n/a
 
      04-11-2009
There are three unique loc/@id values and two unique coverageClass
values. I need to figure out how to output all the unique
combinations of the two (see example under original xml). Can anyone
please help?

<?xml version="1.0" encoding="UTF-8"?>
<company>
<company_bs>
<company_info>
<location>
<loc id="1"/>
</location>
<location>
<loc id="2"/>
</location>
<location>
<loc id="3"/>
</location>
<business>
<businessType>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class2</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class2</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
</businessType>
</business>
</company_info>
</company_bs>
</company>

I would like to end up with all the unique location and class
combinations like so:

<company>
<combo><loc>1</loc><class>Class1</class></combo>
<combo><loc>1</loc><class>Class2</class></combo>
<combo><loc>2</loc><class>Class1</class></combo>
<combo><loc>2</loc><class>Class2</class></combo
<combo><loc>3</loc><class>Class1</class></combo>
<combo><loc>3</loc><class>Class2</class></combo>
</company>
 
Reply With Quote
 
 
 
 
Martin Honnen
Guest
Posts: n/a
 
      04-12-2009
johkar wrote:

> I would like to end up with all the unique location and class
> combinations like so:
>
> <company>
> <combo><loc>1</loc><class>Class1</class></combo>
> <combo><loc>1</loc><class>Class2</class></combo>
> <combo><loc>2</loc><class>Class1</class></combo>
> <combo><loc>2</loc><class>Class2</class></combo
> <combo><loc>3</loc><class>Class1</class></combo>
> <combo><loc>3</loc><class>Class2</class></combo>
> </company>


With XSLT 2.0 (as supported by Saxon from http://saxon.sourceforge.net/
and AltovaXML tools from http://www.altova.com/ and Gestalt from
http://gestalt.sourceforge.net/) you can use

<xsl:stylesheet
xmlnssl="http://www.w3.org/1999/XSL/Transform"
version="2.0">

<xsl:variable name="root" select="/"/>

<xsl:template match="company">
<xsl:copy>
<xsl:for-each
select="distinct-values(company_bs/company_info/location/loc/@id)">
<xsl:variable name="id" select="."/>
<xsl:for-each
select="distinct-values($root/company/company_bs/company_info/business/businessType/businessClass/class/coverageClass)">
<combo><loc><xsl:value-of
select="$id"/></loc><class><xsl:value-of select="."/></class></combo>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

With XSLT 1.0 you can apply Muenchian grouping:

<xsl:stylesheet
xmlnssl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:key name="by-id" match="loc" use="@id"/>

<xsl:key name="by-class" match="coverageClass" use="."/>

<xsl:template match="company">
<xsl:copy>
<xsl:for-each
select="company_bs/company_info/location/loc[generate-id() =
generate-id(key('by-id', @id)[1])]">
<xsl:variable name="id" select="@id"/>
<xsl:for-each
select="/company/company_bs/company_info/business/businessType/businessClass/class/coverageClass[generate-id()
= generate-id(key('by-class', .)[1])]">
<combo><loc><xsl:value-of
select="$id"/></loc><class><xsl:value-of select="."/></class></combo>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

--

Martin Honnen
http://JavaScript.FAQTs.com/
 
Reply With Quote
 
 
 
 
David Carlisle
Guest
Posts: n/a
 
      04-12-2009
in xslt2 something like the following. If you are stuck with xslt 1,
then the usual technique is "muenchian grouping" (google for that).

David


<xsl:stylesheet version="2.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:template match="/">
<xsl:variable name="l"
select="distinct-values(/company/company_bs/company_info/location/loc/@id)"/>
<xsl:variable name="c"
select="distinct-values(/company/company_bs/company_info/business/businessType/businessClass/class/coverageClass)"/>

<company>
<xsl:for-each select="$l">
<xsl:variable name="loc" select="."/>
<xsl:for-each select="$c">
<combo><loc><xsl:value-of select="$loc"/></loc><class><xsl:value-of
select="."/></class></combo>
</xsl:for-each>
</xsl:for-each>
</company>
</xsl:template>

</xsl:stylesheet>
 
Reply With Quote
 
johkar
Guest
Posts: n/a
 
      04-12-2009
On Apr 12, 10:52*am, David Carlisle <(E-Mail Removed)>
wrote:
> in xslt2 something like the following. If you are stuck with xslt 1,
> then the usual technique is "muenchian grouping" (google for that).
>
> David
>
> <xsl:stylesheet version="2.0"
> xmlnssl="http://www.w3.org/1999/XSL/Transform">
>
> <xslutput indent="yes"/>
> <xsl:strip-space elements="*"/>
>
> <xsl:template match="/">
> <xsl:variable name="l"
> select="distinct-values(/company/company_bs/company_info/location/loc/@id)"*/>
> <xsl:variable name="c"
> select="distinct-values(/company/company_bs/company_info/business/businessT*ype/businessClass/class/coverageClass)"/>
>
> <company>
> <xsl:for-each select="$l">
> <xsl:variable name="loc" select="."/>
> <xsl:for-each select="$c">
> <combo><loc><xsl:value-of select="$loc"/></loc><class><xsl:value-of
> select="."/></class></combo>
> </xsl:for-each>
> </xsl:for-each>
> </company>
> </xsl:template>
>
> </xsl:stylesheet>


Thanks for the reply.
 
Reply With Quote
 
johkar
Guest
Posts: n/a
 
      04-13-2009
On Apr 12, 5:03*am, Martin Honnen <(E-Mail Removed)> wrote:
> johkar wrote:
> > I would like to end up with all the unique location and class
> > combinations like so:

>
> > <company>
> > <combo><loc>1</loc><class>Class1</class></combo>
> > <combo><loc>1</loc><class>Class2</class></combo>
> > <combo><loc>2</loc><class>Class1</class></combo>
> > <combo><loc>2</loc><class>Class2</class></combo
> > <combo><loc>3</loc><class>Class1</class></combo>
> > <combo><loc>3</loc><class>Class2</class></combo>
> > </company>

>
> With XSLT 2.0 (as supported by Saxon fromhttp://saxon.sourceforge.net/
> and AltovaXML tools fromhttp://www.altova.com/and Gestalt fromhttp://gestalt.sourceforge.net/) you can use
>
> <xsl:stylesheet
> * *xmlnssl="http://www.w3.org/1999/XSL/Transform"
> * *version="2.0">
>
> * *<xsl:variable name="root" select="/"/>
>
> * *<xsl:template match="company">
> * * *<xsl:copy>
> * * * *<xsl:for-each
> select="distinct-values(company_bs/company_info/location/loc/@id)">
> * * * * *<xsl:variable name="id" select="."/>
> * * * * *<xsl:for-each
> select="distinct-values($root/company/company_bs/company_info/business/businessType/businessClass/class/coverageClass)">
> * * * * * *<combo><loc><xsl:value-of
> select="$id"/></loc><class><xsl:value-of select="."/></class></combo>
> * * * * * *<xsl:value-of select="' '"/>
> * * * * *</xsl:for-each>
> * * * *</xsl:for-each>
> * * *</xsl:copy>
> * *</xsl:template>
>
> </xsl:stylesheet>
>
> With XSLT 1.0 you can apply Muenchian grouping:
>
> <xsl:stylesheet
> * *xmlnssl="http://www.w3.org/1999/XSL/Transform"
> * *version="1.0">
>
> * *<xsl:key name="by-id" match="loc" use="@id"/>
>
> * *<xsl:key name="by-class" match="coverageClass" use="."/>
>
> * *<xsl:template match="company">
> * * *<xsl:copy>
> * * * *<xsl:for-each
> select="company_bs/company_info/location/loc[generate-id() =
> generate-id(key('by-id', @id)[1])]">
> * * * * *<xsl:variable name="id" select="@id"/>
> * * * * *<xsl:for-each
> select="/company/company_bs/company_info/business/businessType/businessClass/class/coverageClass[generate-id()
> = generate-id(key('by-class', .)[1])]">
> * * * * * *<combo><loc><xsl:value-of
> select="$id"/></loc><class><xsl:value-of select="."/></class></combo>
> * * * * * *<xsl:value-of select="' '"/>
> * * * * *</xsl:for-each>
> * * * *</xsl:for-each>
> * * *</xsl:copy>
> * *</xsl:template>
>
> </xsl:stylesheet>
>
> --
>
> * * * * Martin Honnen
> * * * *http://JavaScript.FAQTs.com/


Actually I have a slightly different scenario than I envisioned. loc/
@id has its own businessType and I need to know the coverageClass's
that are available to that location....they are no longer in the same
nodeset.

<?xml version="1.0" encoding="UTF-8"?>
<company>
<company_bs>
<company_info>
<location>
<loc id="1"/>
</location>
<location>
<loc id="2"/>
</location>
<location>
<loc id="3"/>
</location>
<business>
<businessType loc="1">
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class2</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class2</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
</businessType>
<businessType loc="2">
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class3</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class3</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class4</coverageClass>
</class>
</businessClass>
</businessType>
<businessType loc="3">
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class2</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class2</coverageClass>
</class>
</businessClass>
<businessClass>
<class>
<coverageClass>Class1</coverageClass>
</class>
</businessClass>
</businessType>
</business>
</company_info>
</company_bs>
</company>

I would like to end up with all the unique location and class
combinations like so:

<company>
<combo><loc>1</loc><class>Class1</class></combo>
<combo><loc>1</loc><class>Class2</class></combo>
<combo><loc>2</loc><class>Class1</class></combo>
<combo><loc>2</loc><class>Class3</class></combo>
<combo><loc>2</loc><class>Class4</class></combo
<combo><loc>3</loc><class>Class1</class></combo>
<combo><loc>3</loc><class>Class2</class></combo>
</company>
 
Reply With Quote
 
Martin Honnen
Guest
Posts: n/a
 
      04-14-2009
johkar wrote:

> Actually I have a slightly different scenario than I envisioned. loc/
> @id has its own businessType and I need to know the coverageClass's
> that are available to that location....they are no longer in the same
> nodeset.



Here is an XSLT 2.0 solution:

<xsl:stylesheet
xmlnssl="http://www.w3.org/1999/XSL/Transform"
version="2.0">

<xsl:strip-space elements="*"/>
<xslutput method="xml" indent="yes"/>

<xsl:key name="bt-by-loc" match="businessType" use="@loc"/>
<xsl:variable name="root" select="/"/>

<xsl:template match="company">
<xsl:for-each
select="distinct-values(company_bs/company_info/location/loc/@id)">
<xsl:variable name="id" select="."/>
<xsl:for-each select="distinct-values(key('bt-by-loc', $id,
$root)/businessClass/class/coverageClass)">
<combo>
<loc>
<xsl:value-of select="$id"/>
</loc>
<class>
<xsl:value-of select="."/>
</class>
</combo>
</xsl:for-each>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>


--

Martin Honnen
http://JavaScript.FAQTs.com/
 
Reply With Quote
 
johkar
Guest
Posts: n/a
 
      04-19-2009
On Apr 14, 4:51*am, Martin Honnen <(E-Mail Removed)> wrote:
> johkarwrote:
> > Actually I have a slightly different scenario than I envisioned. *loc/
> > @id has its own businessType and I need to know the coverageClass's
> > that are available to that location....they are no longer in the same
> > nodeset.

>
> Here is an XSLT 2.0 solution:
>
> <xsl:stylesheet
> * *xmlnssl="http://www.w3.org/1999/XSL/Transform"
> * *version="2.0">
>
> * *<xsl:strip-space elements="*"/>
> * *<xslutput method="xml" indent="yes"/>
>
> * *<xsl:key name="bt-by-loc" match="businessType" use="@loc"/>
> * *<xsl:variable name="root" select="/"/>
>
> * *<xsl:template match="company">
> * * *<xsl:for-each
> select="distinct-values(company_bs/company_info/location/loc/@id)">
> * * * *<xsl:variable name="id" select="."/>
> * * * *<xsl:for-each select="distinct-values(key('bt-by-loc', $id,
> $root)/businessClass/class/coverageClass)">
> * * * * *<combo>
> * * * * * *<loc>
> * * * * * * *<xsl:value-of select="$id"/>
> * * * * * *</loc>
> * * * * * *<class>
> * * * * * * *<xsl:value-of select="."/>
> * * * * * *</class>
> * * * * *</combo>
> * * * *</xsl:for-each>
> * * *</xsl:for-each>
> * *</xsl:template>
>
> </xsl:stylesheet>
>
> --
>
> * * * * Martin Honnen
> * * * *http://JavaScript.FAQTs.com/


Thanks Martin, I was called away and couldn't aknowledge your answer.
 
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
Finding unique combinations from two nodesets johkar XML 2 04-12-2009 04:39 PM
A case with Combinations in Sets anirbid.banerjee@gmail.com Perl Misc 1 02-19-2008 03:46 PM
xsl variable $node/text() but $node can non-node-set help! Tjerk Wolterink XML 2 08-24-2006 03:28 AM
How to set the node indent property between the parent node and the leaf node viveknatani@gmail.com ASP .Net 0 02-13-2006 07:11 PM
Generating combinations from multiple sets Srinivas Jonnalagadda Ruby 1 01-16-2006 12:19 PM



Advertisments