Home > OS >  Problem with multiple groups while transforming XML using XSLT
Problem with multiple groups while transforming XML using XSLT

Time:01-29

I had a problem with grouping while transforming xml to xml using xslt version 1.0

@michael.hor257k has kindly provided the solution to fix it. Link below:

Problem transforming XML groups with XSLT

However, I still need some improvements in the resultant output.

  1. I would like to change the tag in output result “” to omitting the ‘namespace’ and getting either the tag name in camelCase (with ‘s’ in lower case in this example) or by replacing it with completely a new tag label like ‘document’ (). Please see that the input still contains stays the same as it is.

  2. I want to have another super group like in the output xml. For example if I have two addresses in the input, i would like to keep them under …….….. . I tried adding another template as but it resulted only one super group coming up, not both.


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="addressFields">
<member name="addressLine1"> flat 3 Oxford house </member>
<member name="addressLine2"> Baker street </member>
<member name="town"> London </member>
<member name="postCode"> W1U 6BZ </member>
<member name="country"> UK </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: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"/>
            <xsl:apply-templates select="group[@name!='transaction']"/>
            <transactions>
                <xsl:apply-templates select="group[@name='transaction']"/>
            </transactions>
    </xsl:copy>
    <xsl:copy>
        <xsl:apply-templates select="field"/>
            <xsl:apply-templates select="group[@name!='addressFields']"/>
            <addressFieldsGroup>
                <xsl:apply-templates select="group[@name='addressFields']"/>
            </addressFieldsGroup>
        </grouping>
    </xsl:copy>
</xsl:template>

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

<xsl:template match="text()">
   <xsl:value-of select="normalize-space()"/>
</xsl:template>

</xsl:stylesheet>

Actual output



    <?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>
         <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>  
      <addressFieldsGroup>
      <addressFields>
         <addressLine1>flat 2 ted apartments</addressLine1>
         <addressLine2>samurai street</addressLine2>
         <town>Jaisalmer</town>
         <postCode>678222</postCode>
         <country>Indonesia</country>
     </addressFields>
      <addressFields>
         <addressLine1>flat 3 Oxford house</addressLine1>
         <addressLine2>Baker street</addressLine2>
         <town>London</town>
         <postCode>W1U 6BZ</postCode>
         <country>UK</country>
     </addressFields>
     </addressFieldsGroup>
    </Statement>

If you see above, only one group name is coming up but not the other. I have given below the expected output. Kindly check and advise.


Expected output


    <?xml version="1.0" encoding="UTF-8"?>
    **<statement>**
       <statementNumber>25</statementNumber>
       <Online>Yes</Online>
       <iban>xxxx</iban>
     **  <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>**
      <addressFieldsGroup>
      <addressFields>
         <addressLine1>flat 2 ted apartments</addressLine1>
         <addressLine2>samurai street</addressLine2>
         <town>Jaisalmer</town>
         <postCode>678222</postCode>
         <country>Indonesia</country>
     </addressFields>
      <addressFields>
         <addressLine1>flat 3 Oxford house</addressLine1>
         <addressLine2>Baker street</addressLine2>
         <town>London</town>
         <postCode>W1U 6BZ</postCode>
         <country>UK</country>
     </addressFields>
     </addressFieldsGroup>
    **</statement>**

Thank you!

Explained in detail in the above section

CodePudding user response:

Simply remove the repetitious and overriding apply-templates and directly use new root name:

<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">
      <statement>
          <xsl:apply-templates select="field"/>
          <transactions>
              <xsl:apply-templates select="group[@name='transaction']"/>
          </transactions>
          <addressFieldsGroup>
              <xsl:apply-templates select="group[@name='addressFields']"/>
          </addressFieldsGroup>
      </statement>
  </xsl:template>
  
  <xsl:template match="group | field | member">
      <xsl:element name="{@name}">
          <xsl:apply-templates/>
      </xsl:element>
  </xsl:template>
  
  <xsl:template match="text()">
     <xsl:value-of select="normalize-space()"/>
  </xsl:template>
</xsl:stylesheet>

Online Demo

  • Related