Home > OS >  Problem transforming XML groups with XSLT
Problem transforming XML groups with XSLT

Time:01-26

I am having problem with grouping while transforming xml to xml using xslt. I found out where the problem comes from but still don't know how to fix it.

I am unable to fetch the group name/multiple groups in the output after XSLT transformation. I'm only able to fetch the group name provided in the XSLT code but not the group name present in "input xml". Please be noted that our system doesn't support for-each-group and current-group() functions, resulting in XML parse error.

This is the sample input

<?xml version="1.0" encoding="UTF-8"?>
<Statement xmlns:xsi="http://www.w.org/2001/XMLSchemainstance">
<field name="statementNumber"> 25 </field>
<field name="Online"> Yes </field>
<field name="iban"> xxxx </field>
<group name="addressFields">
<member name="addressLine1"> flat 2 ted apartments </member>
<member name="addressLine2"> samurai street </member>
<member name="town"> Jaisalmer </member>
<member name="postCode"> 678222 </member>
<member name="country"> Indonesia </member>
</group>
<group name="transaction">
<member name="type"> cash </member>
<member name="amount"> 5228 </member>
<member name="txnDate"> 28 oct 2022 </member>
<member name="reference"> ATM withdrawal </member>
</group>
<group name="transaction">
<member name="type"> card </member>
<member name="amount"> 3378 </member>
<member name="txnDate"> 28 nov 2022 </member>
<member name="reference"> Super market purchase </member>
</group>
</Statement>

XSLT code snippet:

<xsl:output method="xml" indent="yes">
<xsl:template match="/">
<Statement>
  <xsl:for-each select="Statement/field">
    <xsl:element name="{@name}">
    <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
  <xsl:element name="grouping">
    <xsl:for-each select="Statement/group/member">
      <xsl:element name="{@name}">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:for-each>     
   </xsl:element>
</Statement>

Actual output (incorrect - need group names):

<?xml version="1.0" encoding="UTF-8"?>
<Statement>
<statementNumber>25</statementNumber>
<Online>Yes</Online>
<iban>xxxx</iban>
<grouping>
<addressLine1>flat 2 ted apartments</addressLine1>
<addressLine2>samurai street</addressLine2>
<town>Jaisalmer</town>
<postCode>678222</postCode>
<country>Indonesia</country>
<type>cash</type>
<amount>5228</amount>
<txnDate>28 oct 2022</txnDate>
<reference>ATM withdrawal</reference>
<type>card</type>
<amount>3378</amount>
<txnDate>28 nov 2022</txnDate>
<reference>Super market purchase</reference>
</grouping>
</Statement>

If you see above, the group names are completely missing; not appearing in the output. I tried many ways to achieve it, but either group name is missing or all the group fields are missing. I'm unable to fetch both of them. Moreover, I have a requirement of adding all <transaction> group blocks within another super group block <transactions>

Expected output

<?xml version="1.0" encoding="UTF-8"?>
<Statement>
<statementNumber>25</statementNumber>
<Online>Yes</Online>
<iban>xxxx</iban>
<grouping>
<addressFields>
<addressLine1>flat 2 ted apartments</addressLine1>
<addressLine2>samurai street</addressLine2>
<town>Jaisalmer</town>
<postCode>678222</postCode>
<country>Indonesia</country>
</addressFields>
<transactions>
<transaction>
<type>cash</type>
<amount>5228</amount>
<txnDate>28 oct 2022</txnDate>
<reference>ATM withdrawal</reference>
</transaction>
<transaction>
<type>card</type>
<amount>3378</amount>
<txnDate>28 nov 2022</txnDate>
<reference>Super market purchase</reference>
</transaction>
</transactions>
</grouping>
</Statement>

CodePudding user response:

I am guessing (!) you want to do something like:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/Statement">
    <xsl:copy>
        <xsl:apply-templates select="field"/>
        <grouping>
            <xsl:apply-templates select="group[@name!='transaction']"/>
            <transactions>
                <xsl:apply-templates select="group[@name='transaction']"/>
            </transactions>
        </grouping>
    </xsl:copy>
</xsl:template>

<xsl:template match="group | field | member">
    <xsl:element name="{@name}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Given a well-formed (!) XML as the input:

XML

<Statement xmlns:xsi="http://www.w.org/2001/XMLSchemainstance">
<field name="statementNumber"> 25 </field>
<field name="Online"> Yes </field>
<field name="iban"> xxxx </field>
<group name="addressFields">
<member name="addressLine1"> flat 2 ted apartments </member>
<member name="addressLine2"> samurai street </member>
<member name="town"> Jaisalmer </member>
<member name="postCode"> 678222 </member>
<member name="country"> Indonesia </member>
</group>
<group name="transaction">
<member name="type"> cash </member>
<member name="amount"> 5228 </member>
<member name="txnDate"> 28 oct 2022 </member>
<member name="reference"> ATM withdrawal </member>
</group>
<group name="transaction">
<member name="type"> card </member>
<member name="amount"> 3378 </member>
<member name="txnDate"> 28 nov 2022 </member>
<member name="reference"> Super market purchase </member>
</group>
</Statement>

this will return:

Result

<?xml version="1.0" encoding="UTF-8"?>
<Statement xmlns:xsi="http://www.w.org/2001/XMLSchemainstance">
   <statementNumber> 25 </statementNumber>
   <Online> Yes </Online>
   <iban> xxxx </iban>
   <grouping>
      <addressFields>
         <addressLine1> flat 2 ted apartments </addressLine1>
         <addressLine2> samurai street </addressLine2>
         <town> Jaisalmer </town>
         <postCode> 678222 </postCode>
         <country> Indonesia </country>
      </addressFields>
      <transactions>
         <transaction>
            <type> cash </type>
            <amount> 5228 </amount>
            <txnDate> 28 oct 2022 </txnDate>
            <reference> ATM withdrawal </reference>
         </transaction>
         <transaction>
            <type> card </type>
            <amount> 3378 </amount>
            <txnDate> 28 nov 2022 </txnDate>
            <reference> Super market purchase </reference>
         </transaction>
      </transactions>
   </grouping>
</Statement>

Note that this has nothing to do with grouping; your input is already grouped.

  • Related