RE: [xsl] Grouping problem - Duplicates

Subject: RE: [xsl] Grouping problem - Duplicates
From: Sarah <sarah10@xxxxxxxxxxx>
Date: Sat, 01 May 2004 08:38:19 +0200
Hi Peter,

Thanks for the xslt, but the thing is, you referred to the content of the <Area> node-names as hard coded, while I cannot do that.
The point is that it should be generic, and collect whatever might appear in the <Area> section. The XML is just a snipped example of the real content.


So, I do need the loop using the 'areas' key to get that info, unless I didn't understand your example.
If so, can you please explain where am I wrong?


Sarah

At 19:39 30/4/2004, you wrote:
Sarah,

Unless I am misunderstanding something of your requirements, I think that your
problem is easier than you are making it. It does look like a typical grouping
problem, but I don't think you need to use the complicated techniques that you
are trying to learn to use.


>> Here is a copy of my XML file called Company.xml:
>>
>> <Company>
>> <Suppliers>
>> <Area>
>> <North>Supp 1 Nor</North>
>> <South>Supp 1 Sou</South>
>> <Center>Supp 1 Cntr</Center>
>> <North>Supp 2 Nor</North>
>> <North>Supp 3 Nor</North>
>> <South>Supp 2 Sou</South>
>> <South>Supp 3 Sou</South>
>> <Center>Supp 2 Cntr</Center>
>> <Center>Supp 3 Cntr</Center>
>> <North>Smith Suppliers LTD.</North>
>> <South>Smith Suppliers LTD.</South>
>> <Center>Sundance suppliers Cntr</Center>
>> </Area>
>> <SalesPeople>
>> <SalesPerson>
>> <Name>
>> <LastName>lName Supp 1</LastName>
>> <FirstName>John</FirstName>
>> </Name>
>> <Title>Manager</Title>
>> <Supplier>Supp 1 Nor</Supplier>
>> <Supplier>Supp 1 Sou</Supplier>
>> <Supplier>Supp 1 Cntr</Supplier>
>> <Supplier>Supp 2 Cntr</Supplier>
>> <Supplier>Supp 3 Cntr</Supplier>
>> <Supplier>Smith Suppliers LTD.</Supplier>
>> <Supplier>Smith Suppliers LTD.</Supplier>
>> <Supplier>Sundance suppliers Cntr</Supplier>
>> </SalesPerson>
>> <SalesPerson>
>> <Name>
>> <LastName>lName Supp 2</LastName>
>> <FirstName>Kathy</FirstName>
>> </Name>
>> <Title>CEO</Title>
>> <Supplier>Supp 2 Nor</Supplier>
>> <Supplier>Supp 2 Sou</Supplier>
>> <Supplier>Supp 2 Cntr</Supplier>
>> <Supplier>Supp 1 Cntr</Supplier>
>> <Supplier>Supp 2 Cntr</Supplier>
>> <Supplier>Supp 3 Cntr</Supplier>
>> <Supplier>Smith Suppliers LTD.</Supplier>
>> </SalesPerson>


(snipped...)

>>                      </SalesPeople>
>>              </Suppliers>
>> </Company>

>> I would like to see the following output:
>>
>> Sales People by Areas
>> Center
>>
>> Dave lName Samuel
>> John lName Supp 1
>> Kathy lName Supp 2
>> Dan lName Supp 3
>>
>> North
>>
>> John lName Supp 1
>> Kathy lName Supp 2
>> George lName Apprentice
>> Dave lName Samuel
>> Dan lName Supp 3
>>
>> South
>>
>> John lName Supp 1
>> Kathy lName Supp 2
>> Dave lName Samuel
>> Dan lName Supp 3


One potential solution is to start at the child nodes of Area and apply templates to any Salesperson who fits the criteria of having the particular entry listed in their suppliers list. So, starting with the template matching Area,

<xsl:template match="Area">
<p>
<xsl:text>Center</xsl:text>
<xsl:apply-templates select="../SalesPeople/SalesPerson[Supplier
= current()/Center]" />
</p>
</xsl:template>


This will apply templates to any SalesPerson who matches the criteria where they
have one supplier whose text value is equal to one node named Center's text
value. The power of the equality operator on node sets is that it will return
true if it is true for any Supplier and any other Center elements.


This can certainly be made more generic if you have more than just three defined
Area's but I recommend not making overly complicated and generic unless you need
it. If you are unable to work out to group on the Area child nodes and make it
more generic, post again and I or someone else can help figure out that part of
it.


Here is the full stylesheet (the HTML is certainly different than will want, but
this should get you started with the XSLT logic):


<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"
encoding="UTF-8"/>


<xsl:template match="/">
        <xsl:apply-templates select="Company"/>
</xsl:template>

<xsl:template match="Company">
        <div>
                <h1>Sales People by Areas</h1>
                <xsl:apply-templates select="Suppliers/Area" />
        </div>
</xsl:template>

<xsl:template match="Area">
<p>
<xsl:text>Center</xsl:text>
<xsl:apply-templates select="../SalesPeople/SalesPerson[Supplier
= current()/Center]" />
</p>


<p>
<xsl:text>North</xsl:text>
<xsl:apply-templates select="../SalesPeople/SalesPerson[Supplier
= current()/North]" />
</p>


<p>
<xsl:text>South</xsl:text>
<xsl:apply-templates select="../SalesPeople/SalesPerson[Supplier
= current()/South]" />
</p>
</xsl:template>


<xsl:template match="SalesPerson">
        <p>
                <xsl:value-of select="Name/FirstName" />
                <xsl:text> </xsl:text>
                <xsl:value-of select="Name/LastName" />
        </p>
</xsl:template>

</xsl:stylesheet>


Hope this helps.


-Peter


--------------------------------------------
This message contains useless information that may be confidential and
monotonous. Unless you are the intended recipient, know the intended recipient
in the biblical sense, or are authorized to receive this message for the
intended recipient while the intended recipient is being lazy, you may not use,
abuse, copy, masticate, disseminate, or disinter to anyone, including the
indented recipient, the message or any information contained in the
aforementioned message. If you have received the message in error, please advise
the sender by reply telegraph, blame your system administrator for all of the
world's problems, and delete the message immediately. Thank you very much.
Have a good day.

Current Thread