Subject: Re: [xsl] How to do this unique grouping on XML using XSLT 1.0 From: Amit Agarwal <aagarwal123@xxxxxxxxx> Date: Tue, 19 Jun 2012 23:06:45 +0530 |
Hi Scott, Thanks for the response. My target xml is little bit different. Grouping logic that you mentioned is correct but I'm facing issue to create the target xml. Input xml: ------------ <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> ------------- Target Xml: -------------- <Root> <Drug> <medicinalproduct>BPM Infra</medicinalproduct> <obtaindrugcountry>US</obtaindrugcountry> <activesubstancename>1234</activesubstancename> </Drug> <Drug> <medicinalproduct>Multistandard VCR</medicinalproduct> <obtaindrugcountry>UK</obtaindrugcountry> </Drug> <Drug> <medicinalproduct>Pharmaceuticals</medicinalproduct> <obtaindrugcountry>IN</obtaindrugcountry> </Drug> <Drug> <medicinalproduct>Different Product name</medicinalproduct> <activesubstancename>456</activesubstancename> </Drug> </Root> --- As you can see, my target xml has different tags name. So, instead of copying <xsl:copy-of select="key('drug', self::ebo:DrugSafetyReportDrug/ebo:MedicinalProductName | self::ebo:DrugSafetyReportMedicalDevice/ebo:MedicalDeviceName)/*[not(self::eb o:MedicinalProductName or self::ebo:MedicalDeviceName)]"/> I have to transform it to target elements. Thanks, Amit > On Tue, Jun 19, 2012 at 8:02 PM, Scott Trenda <Scott.Trenda@xxxxxxxx> wrote: >> 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::MedicinalP roductName 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 -> |
---|---|---|
Re: [xsl] How to do this unique gro, Amit Agarwal | Thread | RE: [xsl] How to do this unique gro, Scott Trenda |
Re: [xsl] xsl:include, David Carlisle | Date | RE: [xsl] How to do this unique gro, Scott Trenda |
Month |