0

I am struggling to get sorting the values from multiple arrays groups. I want group the values based upon same year and same month respective of same array and multiple arrays.

Input XML

<?xml version="1.0" ?>
<message:GenericData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:generic="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic"
 xmlns:message="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message"
 xmlns:common="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common">

    <message:DataSet structureRef="BBK_SEDI" >
        <generic:Series> 
            <generic:SeriesKey>  
                <generic:Value id="BBK_SEDI_CALCULATION" value="ABZINS7"></generic:Value>        
            </generic:SeriesKey>
            <generic:Attributes>
                <generic:Value id="BBK_ID" value="BBSDI.M.ABZINS7.R01"></generic:Value>
            </generic:Attributes>
            <generic:Obs>
                <generic:ObsDimension value="2015-01"></generic:ObsDimension>
                <generic:ObsValue value="3.07"></generic:ObsValue>
            </generic:Obs>
            <generic:Obs>
                <generic:ObsDimension value="2016-01"></generic:ObsDimension>
                <generic:ObsValue value="3.05"></generic:ObsValue> 
            </generic:Obs>
        </generic:Series>
        <generic:Series>
            <generic:SeriesKey>       
                <generic:Value id="BBK_SEDI_CALCULATION" value="ABZINS7"></generic:Value>                       
            </generic:SeriesKey>
            <generic:Attributes>
                <generic:Value id="BBK_ID" value="BBSDI.M.ABZINS7.R02"></generic:Value>
            </generic:Attributes>
            <generic:Obs>
                <generic:ObsDimension value="2015-01"></generic:ObsDimension>
                <generic:ObsValue value="1.07"></generic:ObsValue>
            </generic:Obs>
            <generic:Obs>
                <generic:ObsDimension value="2016-01"></generic:ObsDimension>
                <generic:ObsValue value="1.05"></generic:ObsValue>
            </generic:Obs> 
        </generic:Series>
    </message:DataSet>
</message:GenericData>

My XSLT provides gives the values from same arrays not from different arrays

**XSLT**

    <?xml version="1.0" ?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:java="http://xml.apache.org/xslt/java" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:n0="http://sap.com/xi/SAPGlobal20/Global" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:generic="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic"
     xmlns:message="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message"
     xmlns:common="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common"
     xmlns:ns1="urn:siemens.com:Rates:SIE_I_T_S4_FIN1.0"
    exclude-result-prefixes="xs xsi map generic java n0 message common ns1 ext exsl" xmlns:xslt-version="MonthlyDiscounts_XSLT_26/06/2022" xmlns:exsl="http://exslt.org/common" xmlns:ext="http://exslt.org/common">
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
        <xsl:strip-space elements="*"/>
        <xsl:template match="message:DataSet">
            <ns1:DiscountInterestRatePercent>
            <xsl:for-each select="./generic:Series " >
            <xsl:if test= " ./generic:SeriesKey/generic:Value/@value = 'ABZINS7'">
            
                <Data>
                    <Year>
                    <xsl:value-of select="substring-before(./generic:Obs/generic:ObsDimension/@value,'-')"/>
                    </Year>
                    <Month>
                        <xsl:value-of select="substring-after(./generic:Obs/generic:ObsDimension/@value,'-')"/>
                    </Month>
                    <RatePercentList>
                    <xsl:for-each select="./generic:Obs" >
                        <RatePercent>
                           <xsl:value-of select="./generic:ObsValue/@value"/>
                        </RatePercent>
                    </xsl:for-each>
                    </RatePercentList>
                </Data>
            </xsl:if>
            </xsl:for-each>
                
            </ns1:DiscountInterestRatePercent>
        </xsl:template>
        </xsl:stylesheet>

Expected output

I am expecting an output based upon below format

<ns1:DiscountInterestRatePercent xmlns:xslt-version="MonthlyDiscounts_XSLT_26/06/2022"
                                                                xmlns:ns1="urn:ates:SI">
   <Data>
      <Year>2015</Year>
      <Month>01</Month>
      <RatePercentList>
         <RatePercent>3.07</RatePercent>
         <RatePercent>1.07</RatePercent>
      </RatePercentList>
   </Data>
   <Data>
      <Year>2016</Year>
      <Month>01</Month>
      <RatePercentList>
         <RatePercent>3.05</RatePercent>
         <RatePercent>1.05</RatePercent>
        
      </RatePercentList>
   </Data>
</ns1:DiscountInterestRatePercent>

Thank you very much for your help

Best Regards, Sateesh

Sateesh
  • 47
  • 1
  • 5

1 Answers1

0

In XSLT 2.0 you can produce the result you show by:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic">
<xsl:output indent="yes"/>

<xsl:template match="/">
    <ns1:DiscountInterestRatePercent xmlns:xslt-version="MonthlyDiscounts_XSLT_26/06/2022" xmlns:ns1="urn:siemens.com:Rates:SIE_I_T_S4_FIN1.0">
        <xsl:for-each-group select="//Obs" group-by="ObsDimension/@value">
            <Data>
                <Year>
                    <xsl:value-of select="substring-before(current-grouping-key(), '-')"/>
                </Year>
                <Month>
                    <xsl:value-of select="substring-after(current-grouping-key(), '-')"/>
                </Month>
                <RatePercentList>
                    <xsl:for-each select="current-group()">
                        <RatePercent>
                            <xsl:value-of select="ObsValue/@value"/>
                        </RatePercent>
                    </xsl:for-each>
                </RatePercentList>
            </Data>
        </xsl:for-each-group>
    </ns1:DiscountInterestRatePercent>
</xsl:template>

</xsl:stylesheet>

Added:

To include only data from Series whose SeriesKey value is "ABZINS7", change:

<xsl:for-each-group select="//Obs" group-by="ObsDimension/@value">

to:

<xsl:for-each-group select="//Series[SeriesKey/Value/@value='ABZINS7']/Obs" group-by="ObsDimension/@value">

Untested, because your example does not allow testing of this condition.

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • Hello Michael, Your XSLT provides an my expected format of output, However there should be also filter required in the SeriesKey value while grouping these values. because we have multiple SeriesKeys where it requires only respective one. Example of filter – Sateesh Jun 27 '23 at 08:41
  • Sorry, I don't understand what you mean. If you have additional requirements, I suggest you post a new question. – michael.hor257k Jun 27 '23 at 08:47
  • Hi Michael, If condition is also part my actual code, could you please take a look once again in my XSLT – Sateesh Jun 27 '23 at 12:32
  • See the addition to my answer. – michael.hor257k Jun 27 '23 at 12:58
  • Thank you Michael, it resolved my issue – Sateesh Jun 30 '23 at 11:34
  • Hi Michael, Would it be possible to provide code in XSLT 1.0 version? it seems for-each-group is not supported by my application – Sateesh Jun 30 '23 at 12:11
  • If you cannot use XSLT 2.0 then don't tag your question as `xslt-2.0` - and don't say that you need XSLT 2.0 when explicitly asked. – michael.hor257k Jun 30 '23 at 12:37
  • Understood Michael, my understanding was my application supports both XSLT 1.0 and XSLT 2.0. by implementing XSLT 2.0 code is bit lower and easy as compare to XSLT 1.0, for that reason i requested – Sateesh Jun 30 '23 at 12:47
  • Hi Michael, Created a post in XSLT 1.0 – Sateesh Jun 30 '23 at 14:17