[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Grouping output based on value in another document

Subject: Grouping output based on value in another document
From: "Alex Maddern" <alex@xxxxxxxxxxxx>
Date: Mon, 26 May 2008 13:41:29 +1000
 Grouping output based on value in another document
Hi Guys,

Long time reader, first time poster.

I have the following input document which we need to translate into an
aggregated output. The principle is that we filter out multiple instances of
the same alert and only output one of each type. A "Status" is assigned to
each Alert type (@alertid) in a mapping XML which holds several hundred
Alert ID's with their status mapping. Not that it matters but I have heavily
simplified these documents and the sample XSL to avoid confusion and to
focus on the problem I'm about to explain.

I have managed to get the required output working quite happily using
for-each-group, based on alert/@alertid as can be seen in the following
example documents

Input Document:

<someRoot>
  <machineID>ABC123</machineID>
  <alerts>
    <alert alertid="20260" details="Yet more" level="..." /> 
    <alert alertid="26554" details="Something 1" level="..." /> 
    <alert alertid="26554" details="Something 2" level="..." /> 
    <alert alertid="20676" details="Another thing 10" level="..." /> 
    <alert alertid="20676" details="Another thing 11" level="..." /> 
    <alert alertid="20676" details="Another thing 12" level="..." /> 
    <alert alertid="20012" details="More stuff" level="..." /> 
  </alerts>
</someRoot>

Reference Document:

<alertMapping>
    <Alerts>
        <Alert id="20260"  status="Administrator Review" />
        <Alert id="26554"  status="Administrator Review" />
        <Alert id="20676"  status="2nd Line Review" />
        <Alert id="20012"  status="Administrator Review" />
    </Alerts>
</alertMapping>

XSLT Document:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.tek.com/cerify/2007/03/22/reports"
version="1.0">
  <xsl:output method="xml" indent="yes" cdata-section-elements="" />
  <xsl:variable name="cpMappingLists"
select="document('mapping-document.xml')" />
    <xsl:key    name="cpALERTS"            match="Alert"   use="@id" />
  <xsl:template match="/">
    <xsl:variable name="machine">
      <xsl:value-of select="//machineID" />
    </xsl:variable>
    <outputSchema>
        <records>
        <xsl:for-each-group select="//alert" group-by="@alertid">
            <record>
                <machineID><xsl:value-of select="$machine"/></machineID>
                <alertType><xsl:value-of select="@alertid"/></alertType>
                <alertStatus>
                  <xsl:variable name="var1"
select="normalize-space(@alertid)" />
                  <xsl:for-each select="$cpMappingLists">
                    <xsl:value-of select="key( 'cpALERTS', string($var1)
)/@status"/>
                  </xsl:for-each>
                </alertStatus>
            </record>
        </xsl:for-each-group>
        </records>
    </outputSchema>
  </xsl:template>
</xsl:stylesheet>

Output Document #1:

<outputSchema>
  <records>
    <record>
	<machineID>ABC123</machineID>
      <alertType>20260</alertType>
      <alertStatus>Administrator Review</alertStatus>
    </record>
    <record>
	<machineID>ABC123</machineID>
      <alertType>26554</alertType>
      <alertStatus>Administrator Review</alertStatus>
    </record>
    <record>
	<machineID>ABC123</machineID>
      <alertType>20676</alertType>
      <alertStatus>2nd Line Review</alertStatus>
    </record>
    <record>
	<machineID>ABC123</machineID>
      <alertType>20012</alertType>
      <alertStatus>Administrator Review</alertStatus>
    </record>
  </records>
</outputSchema>

HOWEVER, I have now been asked to output only "one record for each Status"
to further simplify the lives of the consumer of the output. They are
apparently able to obtain a full list of alerts but they need to be nudged
into knowing they they are needed too, so one record for each type of Status
is what they now want. The output looking as follows:

Output Document #2

<outputSchema>
  <records>
    <record>
	<machineID>ABC123</machineID>
      <alertStatus>Administrator Review</alertStatus>
    </record>
    <record>
	<machineID>ABC123</machineID>
      <alertStatus>2nd Line Review</alertStatus>
    </record>
  </records>
</outputSchema>

This now looks to me like grouping on the Alert/@status in the MAPPING
DOCUMENT after I have mapped the values through. Anyone have any idea how it
can be accomplished. I have been looking at this for several hours now but
my feeble C# developer brain is in a flip trying to work out how to work
this declaritevly. Is there an elegant solution, a way to create a nodeset
from the grouping using xsl:variable and perhaps map the new values into
that nodeset then use for-each-group on it again ?

Any help GREATLY appreciated

Al

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.