Filter a Muenchian Group

L

la.brunning

Hello,

I am trying to filter a Muenchian grouping I have created. I think I am
fairly close, but I am not quite sure where to apply my filter; its
been some time since I did any work with XSLT. An example of my XML;

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="Structure.xsl" type="text/xsl"?>
<dataroot xmlns:eek:d="urn:schemas-microsoft-com:eek:fficedata">
<CostCentre>
<ServiceOrder>1</ServiceOrder>
<Service>Directorate Management Team</Service>
<ServiceDivisionOrder>10</ServiceDivisionOrder>
<ServiceDivisionName>DMT</ServiceDivisionName>
<SectionOrder>A</SectionOrder>
<Section>Service Management and Development</Section>
<CostCentreID>6000</CostCentreID>
</CostCentre>
<CostCentre>
<ServiceOrder>2</ServiceOrder>
<Service>Commissioning and Partnership Services</Service>
<ServiceDivisionOrder>20</ServiceDivisionOrder>
<ServiceDivisionName>Commissioning and Partnership
Services</ServiceDivisionName>
<SectionOrder>A</SectionOrder>
<Section>Commissioning and Partnerships</Section>
<CostCentreID>600N</CostCentreID>
</CostCentre>

There are several cost centres in each section, several sections in
each service division and several service divisions in each service. I
would like to group by service, service division and then section. So
far I have managed to get the following XSL;

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="AllServices" match="CostCentre" use="Service"/>
<xsl:key name="AllServiceDivisions" match="CostCentre"
use="concat(Service ';' ServiceDivisionName)"/>
<xsl:template match="/">
<html>
<body>
<ol>
<xsl:for-each
select="//CostCentre[generate-id(.)=generate-id(key('AllServices',Service))]">
<xsl:sort select="ServiceOrder" data-type="number" />
<li><xsl:value-of select="Service" /></li>
<xsl:variable name="currentService">
<xsl:value-of select="Service"/>
</xsl:variable>
<ul>
<xsl:for-each
select="//CostCentre[generate-id(.)=generate-id(key('AllServiceDivisions',concat(Service
';' ServiceDivisionName)))] ">
<xsl:sort select="ServiceDivisionOrder" data-type="number" />
<li><xsl:value-of select="ServiceDivisionName" /></li>
</xsl:for-each>
</ul>
</xsl:for-each>
</ol>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

I *think* I have made the variable correctly, but am I totally lost at
where to apply the filter (using $currentService). Currently, as you
can imagine, I get all service divisions in each service, rather than
just the service divisions for that service. I have tried several
syntaxes and several locations but with no such luck. Once I get this
right, I believe I can crack the rest. Can anyone shed any light on
where and how I should apply the filter??? Thanks.
 
J

Joe Kesselman

It'd help if you'd been a bit more specific about how you wanted to
filter this. Since you said you want to filter based on $currentService,
and that's being set from the value of the <Service> element, I presume
your goal is to select only those <CostCentre>s which have a particular
<Service> value.

There are multiple ways you can do this. For example, you might apply
that filtering before you spend time sorting. You can do that by simply
replacing all references to CostCentre with
CostCentre[Service=$interestingService] -- selecting only the
interesting CostCentre(s) -- before applying the other predicates.

Here's one flavor of that, applying minimal changes to your existing
code. Note that I'm taking advantage of the fact that you can apply more
than one predicate, just to keep this modular and easy to read; you
could of course combine this test into the existing select predicate
instead.

<xsl:variable name="interestingService"
select="'Directorate Management Team'"/>
<xsl:for-each
select="//CostCentre[Service=$interestingService][generate-id(.)=generate-id(key('AllServices',Service))]">
<xsl:sort select="ServiceOrder" data-type="number" />
<li><xsl:value-of select="Service" /></li>
<xsl:variable name="currentService">
<xsl:value-of select="Service"/>
</xsl:variable>
<ul>
<xsl:for-each
select="//CostCentre[Service=$interestingService][generate-id(.)=generate-id(key('AllServiceDivisions',concat(Service
';' ServiceDivisionName)))] ">
<xsl:sort select="ServiceDivisionOrder" data-type="number" />
<li><xsl:value-of select="ServiceDivisionName" /></li>
</xsl:for-each>
</ul>
</xsl:for-each>
</ol>


Of course if you're only going to select one specific Service value,
there's no real need to include that value in your Muenchen keying...
but I'm trying to minimize changes to your existing code
 
L

Luke Brunning

It'd help if you'd been a bit more specific about how you wanted to
filter this. Since you said you want to filter based on $currentService,
and that's being set from the value of the <Service> element, I presume
your goal is to select only those <CostCentre>s which have a particular
<Service> value.

Hello Joe,

Sorry, looking back at my post today it is indeed not very clear what I
want. I suppose a more accurate description would be "Grouping" rather
than "Filtering", as that's what the filter is doing; I am creating a
report for an intranet which groups together cost centres in the
relevant areas; Section, Service Division and Service. The data is
exported from an Access database.

Many thanks for the reply; your solution worked perfectly, and slots
into my code to give me just what I need. Hopefully I can now use this
throughout the rest of the reports. Once again thanks for the clear and
concise reply.

Luke
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top