[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
RE: [xsl] How to do this unique grouping on XML using XSLT 1.0
Subject: RE: [xsl] How to do this unique grouping on XML using XSLT 1.0 From: Scott Trenda <Scott.Trenda@xxxxxxxx> Date: Tue, 19 Jun 2012 09:32:43 -0500 |
Pretty easy, overall. Mainly you need to remember that you can register multiple node-set matches under a single key name, and retrieve them all at the same time through one key() call. This allows you to do Muenchian grouping over multiple node-sets whose nodes have similar but not identical structure. After you have the groups, it's just a matter of choosing which element you retrieve for grouping and for the medicinalproduct node. The self:: axis ends up being slightly more succinct than a predicate that checks name(). It's repeated three times here; I don't know if that starts to be a case for pulling out the string itself into an XML entity. YMMV. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="utf-8" indent="yes" omit-xml-declaration="yes" /> <xsl:key name="drug" match="DrugSafetyReportDrug" use="MedicinalProductName" /> <xsl:key name="drug" match="DrugSafetyReportMedicalDevice" use="MedicalDeviceName" /> <xsl:variable name="drugs" select="//DrugSafetyReportDrug | //DrugSafetyReportMedicalDevice" /> <xsl:template match="/*"> <Root> <xsl:for-each select="$drugs[generate-id(key('drug', self::DrugSafetyReportDrug/MedicinalProductName | self::DrugSafetyReportMedicalDevice/MedicalDeviceName)) = generate-id()]"> <Drug> <medicinalproduct> <xsl:value-of select="self::DrugSafetyReportDrug/MedicinalProductName | self::DrugSafetyReportMedicalDevice/MedicalDeviceName" /> </medicinalproduct> <xsl:copy-of select="key('drug', self::DrugSafetyReportDrug/MedicinalProductName | self::DrugSafetyReportMedicalDevice/MedicalDeviceName)/*[not(self::MedicinalProductName or self::MedicalDeviceName)]" /> </Drug> </xsl:for-each> </Root> </xsl:template> </xsl:stylesheet> XSLT2 would be just slightly more convenient here, with <xsl:for-each-group select="//DrugSafetyReportDrug | //DrugSafetyReportMedicalDevice" group-by="self::DrugSafetyReportDrug/MedicinalProductName | self::DrugSafetyReportMedicalDevice/MedicalDeviceName">, and then using current-group() instead of calling key() again... but the underlying logic would stay the same. ~ Scott -----Original Message----- From: Amit Agarwal [mailto:aagarwal123@xxxxxxxxx] Sent: Tuesday, June 19, 2012 8:12 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx; xsl-list-help@xxxxxxxxxxxxxxxxxxxxxx Subject: [xsl] How to do this unique grouping on XML using XSLT 1.0 My input xml looks like: Root> <ReportDrugSafetyReport> <DrugSafetyReportPatient> <DrugSafetyReportDrug> <MedicinalProductName>BPM Infra</MedicinalProductName> <ObtainedCountryCode>US</ObtainedCountryCode> </DrugSafetyReportDrug> <DrugSafetyReportDrug> <MedicinalProductName>Multistandard VCR</MedicinalProductName> <ObtainedCountryCode>UK</ObtainedCountryCode> </DrugSafetyReportDrug> <DrugSafetyReportDrug> <MedicinalProductName>Pharmaceuticals</MedicinalProductName> <ObtainedCountryCode>IN</ObtainedCountryCode> </DrugSafetyReportDrug> </DrugSafetyReportPatient> <DrugSafetyReportMedicalDevice> <MedicalDeviceName>BPM Infra</MedicalDeviceName> <DeviceProductCode>1234</DeviceProductCode> </DrugSafetyReportMedicalDevice> <DrugSafetyReportMedicalDevice> <MedicalDeviceName>Different Product name</MedicalDeviceName> <DeviceProductCode>456</DeviceProductCode> </DrugSafetyReportMedicalDevice> </ReportDrugSafetyReport> </Root> And My target xml is: <Root> <Drug> <medicinalproduct>BPM Infra</medicinalproduct> <ObtainedCountryCode>US</ObtainedCountryCode> <DeviceProductCode>1234</DeviceProductCode> </Drug> <Drug> <medicinalproduct>Multistandard VCR</medicinalproduct> <ObtainedCountryCode>UK</ObtainedCountryCode> </Drug> <Drug> <medicinalproduct>Pharmaceuticals</medicinalproduct> <ObtainedCountryCode>IN</ObtainedCountryCode> </Drug> <Drug> <medicinalproduct>Different Product name</medicinalproduct> <DeviceProductCode>456</DeviceProductCode> </Drug> </Root> Input xml contains two unbounded elements DrugSafetyReportDrug and DrugSafetyReportMedicalDevice. Both of these elements belongs to different parent elements, e.g. <root>ReportDrugSafetyReport/ DrugSafetyReportPatient/DrugSafetyReportDrug and <root>/ReportDrugSafetyReport/DrugSafetyReportMedicalDevice Each of these elements has a set of child elements. Out of which, MedicinalProductName is child element of DrugSafetyReportDrug (DrugSafetyReportDrug/MedicinalProductName) and MedicalDeviceName is child element of DrugSafetyReportMedicalDevice (DrugSafetyReportMedicalDevice/MedicalDeviceName). Target xml has an unbounded element: drug. If MedicinalProductName = MedicalDeviceName then DrugSafetyReportDrug and DrugSafetyReportMedicalDevice should be grouped to a single drug element (in the target xml). Otherwise, there would be a separate drug element for each DrugSafetyReportDrug and DrugSafetyReportMedicalDevice. Thanks for your help!. Thanks, Amit
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] How to do this unique groupin, Amit Agarwal | Thread | Re: [xsl] How to do this unique gro, Amit Agarwal |
Re: [xsl] How to do this tricky eli, Michael Kay | Date | Re: [xsl] How to do this tricky eli, Jo Na |
Month |