Forum Moderators: open
I am doing an XSLT transformation on some XML provided by a webservice. A stripped down version of the XML is pasted at the end of this post. I need to group the information in the DACase/Charge nodes under the ReferralAgency. So an example of the output is:
XYZ Police Dept
---------------
A B
abcd 123
efgh 456
ijkl 789
mnop 012
ABC County Sheriff
------------------
A B
grst 345
Some constraints about the data:
- The Charge element will always contain an IncidentId element
- The Charge/IncidentId value will always exist in one and only one of the Referral/Incident/IncidentId elements
- A Referral element does not always have an Incident element
- A Referral/Incident/IncidentId element can be present with no corresponding Charge/IncidentId element
By using a Key, I can select the Referral nodes by ReferralAgency.
<xsl:key name="referrals-by-agency" match="Referral" use="ReferralAgency" />
For the life of me, however, I cannot figure out a way to traverse the Charge nodes to get the desired output. I thought I had it, but I keep running into the prospect of having column headings on an empty table (which is bad) when there is a Referral without any corresponding Charge (like ReferralId=400 in the XML below).
Is there any way to get the desired output and also avoid any empty tables? Any ideas?
If I had my druthers, the Charge nodes would be appearing under the Incident nodes in the XML. But I don't have them :(
Oh yeah - if it matters, the transformation is being done on the server in .Net.
Thanks for any help!
XML Data follows (I have stripped out everything not pertinent to my question)
-----------
<?xml version="1.0" encoding="utf-8"?>
<DACase>
<DACaseId>10</DACaseId>
<Referral>
<ReferralId>100</ReferralId>
<ReferralAgency>XYZ Police Dept</ReferralAgency>
<Incident>
<IncidentId>1000</IncidentId>
</Incident>
</Referral>
<Referral>
<ReferralId>200</ReferralId>
<ReferralAgency>XYZ Police Dept</ReferralAgency>
<Incident>
<IncidentId>2000</IncidentId>
</Incident>
</Referral>
<Referral>
<ReferralId>300</ReferralId>
<ReferralAgency>ABC County Sheriff</ReferralAgency>
<Incident>
<IncidentId>3000</IncidentId>
</Incident>
</Referral>
<Referral>
<ReferralId>400</ReferralId>
<ReferralAgency>Wazoo PD</ReferralAgency>
</Referral>
<Charge>
<ChargeId>10000</ChargeId>
<IncidentId>1000</IncidentId>
<ElementA>abcd</ElementA>
<ElementB>123</ElementB>
</Charge>
<Charge>
<ChargeId>20000</ChargeId>
<IncidentId>1000</IncidentId>
<ElementA>efgh</ElementA>
<ElementB>456</ElementB>
</Charge>
<Charge>
<ChargeId>30000</ChargeId>
<IncidentId>2000</IncidentId>
<ElementA>ijkl</ElementA>
<ElementB>789</ElementB>
</Charge>
<Charge>
<ChargeId>40000</ChargeId>
<IncidentId>2000</IncidentId>
<ElementA>mnop</ElementA>
<ElementB>012</ElementB>
</Charge>
<Charge>
<ChargeId>50000</ChargeId>
<IncidentId>3000</IncidentId>
<ElementA>qrst</ElementA>
<ElementB>345</ElementB>
</Charge>
</DACase>
Otherwise you might try:
<?xml version="1.0" encoding="iso8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/><xsl:key name="rags" match="//Referral" use="ReferralAgency"/>
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="//Referral[count(. ¦ key('rags', ReferralAgency)[1]) = 1]">
<xsl:if test="ReferralAgency/../Incident/IncidentId = not('')">
<table border="1" bordercolor="#889977">
<tr><td><xsl:value-of select="ReferralAgency" /></td><td>ElementA</td><td>ElementB</td></tr>
<xsl:for-each select="key('rags', ReferralAgency)">
<xsl:variable name="ra" select="."/>
<xsl:for-each select="ReferralAgency/../Incident/IncidentId">
<xsl:if test=". = not('')">
<xsl:variable name="riid" select="."/>
<xsl:for-each select="//Charge/IncidentId">
<xsl:if test=". = $riid">
<tr>
<td><xsl:value-of select="." /></td>
<td><xsl:value-of select="../ElementA" /></td>
<td><xsl:value-of select="../ElementB" /></td>
</tr>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
<br />
</table>
</xsl:if>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
which gives the desired output. You also might search the internet for "+grouping +Muenchian" to read more about the method used.
greetings!
I did resolve this. I will have to compare your suggestion to my solution. I'll post back here later (maybe not today though) with the results of that comparison.
cheers!