2

I have been trying to generate XML file from lists of object of type Customer class. Which i have done successfully.But the structure of my XML file is nested and i want to flatten it out.

Following is my XML file content:

<Customers>
<customer>
    <accessRole>
        <name>Customer Center</name>
        <internalId>14</internalId>
    </accessRole>
    <aging>0.0</aging>
    <category>
        <name>Individual</name>
        <internalId>2</internalId>
    </category>
    <companyName>Wolfe Electronics</companyName>
    <consolAging>0.0</consolAging>
    <consolBalance>0.0</consolBalance>
    <consolDepositBalance>0.0</consolDepositBalance>
    <consolOverdueBalance>0.0</consolOverdueBalance>
    <consolUnbilledOrders>2705.23</consolUnbilledOrders>
    <creditHoldOverride/>
    <dateCreated>2011-06-22T12:30:00+05:30</dateCreated>
    <defaultAddress>US</defaultAddress>
    <displaySymbol>$</displaySymbol>
    <email>suresh@ldbsystems.com</email>
    <emailPreference/>
    <emailTransactions>false</emailTransactions>
    <entityId>A Wolfe</entityId>
    <entityStatus>
        <name>CUSTOMER-Closed Won</name>
        <internalId>13</internalId>
    </entityStatus>
    <externalId>entity-5</externalId>
    <faxTransactions>false</faxTransactions>
    <firstName>A</firstName>
    <firstVisit>2012-02-25T05:43:18+05:30</firstVisit>
    <giveAccess>true</giveAccess>
    <globalSubscriptionStatus/>
    <internalId>-5</internalId>
    <isBudgetApproved>false</isBudgetApproved>
    <isInactive>false</isInactive>
    <isPerson>true</isPerson>
    <lastModifiedDate>2012-12-19T07:12:03+05:30</lastModifiedDate>
    <lastName>Wolfe</lastName>
    <lastPageVisited>login-register</lastPageVisited>
    <lastVisit>2013-02-23T06:10:44+05:30</lastVisit>
    <overrideCurrencyFormat>false</overrideCurrencyFormat>
    <phone>650-555-9788</phone>
    <priceLevel>
        <name>Employee Price</name>
        <internalId>3</internalId>
    </priceLevel>
    <printTransactions>false</printTransactions>
    <receivablesAccount>
        <name>Use System Preference</name>
        <internalId>-10</internalId>
    </receivablesAccount>
    <salesRep>
        <name>Clark Koozer</name>
        <internalId>23</internalId>
    </salesRep>
    <shipComplete>false</shipComplete>
    <stage/>
    <symbolPlacement/>
    <taxItem>
        <name>CA-SAN MATEO</name>
        <internalId>-112</internalId>
    </taxItem>
    <taxable>false</taxable>
    <unbilledOrders>2705.23</unbilledOrders>
    <visits>150</visits>
    <webLead>No</webLead>
</customer>
<customer>
    <accessRole>
        <name>Customer Center</name>
        <internalId>14</internalId>
    </accessRole>
    <aging>0.0</aging>
    <category>
        <name>Corporate</name>
        <internalId>1</internalId>
    </category>
    <consolAging>0.0</consolAging>
    <consolBalance>0.0</consolBalance>
    <consolDepositBalance>0.0</consolDepositBalance>
    <consolOverdueBalance>0.0</consolOverdueBalance>
    <consolUnbilledOrders>76.8</consolUnbilledOrders>
    <creditHoldOverride/>
    <customFieldList>
        <customField/>
    </customFieldList>
    <dateCreated>2011-06-26T12:30:00+05:30</dateCreated>
    <defaultAddress>Anderson Boughton Inc.&lt;br&gt;1488 Main&lt;br&gt;Apt 113&lt;br&gt;Seattle WA 98106&lt;br&gt;US</defaultAddress>
    <displaySymbol>$</displaySymbol>
    <email>boughton751@cscatering.com</email>
    <emailPreference/>
    <emailTransactions>false</emailTransactions>
    <entityId>Anderson Boughton Inc.</entityId>
    <entityStatus>
        <name>CUSTOMER-Closed Won</name>
        <internalId>13</internalId>
    </entityStatus>
    <faxTransactions>false</faxTransactions>
    <firstVisit>2012-07-12T01:30:49+05:30</firstVisit>
    <giveAccess>false</giveAccess>
    <globalSubscriptionStatus/>
    <internalId>75</internalId>
    <isBudgetApproved>false</isBudgetApproved>
    <isInactive>false</isInactive>
    <isPerson>false</isPerson>
    <lastModifiedDate>2012-12-19T11:50:14+05:30</lastModifiedDate>
    <lastPageVisited>HP xw4100</lastPageVisited>
    <lastVisit>2012-07-12T01:30:49+05:30</lastVisit>
    <leadSource>
        <name>Partner Referral</name>
        <internalId>99993</internalId>
    </leadSource>
    <overrideCurrencyFormat>false</overrideCurrencyFormat>
    <partner>
        <name>Online electronics</name>
        <internalId>171</internalId>
    </partner>
    <phone>206-555-1302</phone>
    <priceLevel>
        <name>Base Price</name>
        <internalId>1</internalId>
    </priceLevel>
    <printTransactions>false</printTransactions>
    <receivablesAccount>
        <name>Use System Preference</name>
        <internalId>-10</internalId>
    </receivablesAccount>
    <salesRep>
        <name>A Wolfe</name>
        <internalId>-5</internalId>
    </salesRep>
    <shipComplete>false</shipComplete>
    <stage/>
    <symbolPlacement/>
    <taxable>false</taxable>
    <unbilledOrders>76.8</unbilledOrders>
    <webLead>No</webLead>
</customer>
</Customers>

So i have nested structure for <accessRole> which i want to flatten out like <accessRole-name>and i don't want to display element like <internalId>.

Please find a code snippet of my model:

try {
             FileWriter fileWriter = new FileWriter ("D:\\adapter-framework\\Customer_XML.xml");
             JAXBContext jaxbContext = JAXBContext.newInstance(extractedRecordsArray[0].getClass());
             Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
             fileWriter.append("<Customers>");
             fileWriter.append('\n');
             for(int i = 0; i < extractedRecordsArray.length - 761 ; i++)
             {          
                jaxbMarshaller.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);
                jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                //jaxbMarshaller.marshal(extractedRecordsArray[i],fileWriter);
                jaxbMarshaller.marshal(extractedRecordsArray[i],System.out);
                fileWriter.append('\n');
                AdapterLogger.debug(this.getClass().getName(), "Extracted record number : " + i);
             }        
            fileWriter.append("</Customers>");
            fileWriter.close();
          } catch (JAXBException e) {
            e.printStackTrace();
           }

Please help me out if someone knows about it.

Thanks.

Heena Hussain
  • 3,673
  • 1
  • 20
  • 21
  • 1
    Removing the internalId part is easy. Just assign null to it and it won't appear in the XML. The other part is tricky and I don't know from the top of my head. – Burkhard Jun 18 '13 at 12:11
  • Thanks @Burkhard for your reply (+1 for that) .But what if i have lots of attributes that i don't want in XML file ,then it will be very difficult to set all attribute with null value. – Heena Hussain Jun 18 '13 at 12:16
  • You could mark the elements you do not want with @XmlTransient. Maybe this (http://stackoverflow.com/questions/5044042/jaxb-ignore-element) will help? – Burkhard Jun 18 '13 at 12:46

1 Answers1

1

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

You can use the @XmlPath extension in MOXy to flatten the XML structure.

Customer

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    @XmlPath(".")
    private AccessRole accessRole;

}

AccessRole

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class AccessRole {

    @XmlElement(name="accessRoleName")
    private String name;

}

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Thank you so much for you solution(+1).But i am not able to flatten out the structure using your solution maybe because my AccessRole class is inherited by BaseAccessRole class having property called `name` which is being used by AccessRole class. – Heena Hussain Jun 19 '13 at 07:37
  • Can you please help me further? – Heena Hussain Jun 19 '13 at 10:04
  • @HeenaHussain - Can you update your question to contain a domain model that represents your use case? – bdoughan Jun 19 '13 at 10:26
  • where i should keep my jaxb.properties file?At present i have kept it inside my project folder. – Heena Hussain Jun 19 '13 at 10:59
  • @HeenaHussain - The `jaxb.properties` file goes in the same package as the domain model: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html. – bdoughan Jun 19 '13 at 11:14
  • I have placed `jaxb.properties` file at the right place but `@XmlPath` is still not working for me.Can you please help me out? – Heena Hussain Jun 19 '13 at 12:06
  • @HeenaHussain - Here is a link to a full example you can download and try out: https://github.com/bdoughan/blog20110322 – bdoughan Jun 19 '13 at 12:16