PDA

View Full Version : parsing deep xml structures



sencha_newb
10 May 2012, 3:29 PM
I'm just beginning ext js development and having some real trouble getting parsing of deep xml to work.

I've got an xml file like the following:



<CustomerSummary>
<CustID>1</CustID>
<CustAddresses>
<CustAddress>
<Name>Postal Address</Name>
<Address1>4 Gasmain Way</Address1>
<Address2>Cardiff</Address2>
<Postcode>12345</Postcode>
</CustAddress>
<CustAddress>
<Name>Delivery Address</Name>
<Address1>11 Naf Boulevard</Address1>
<Address2>Cardiff</Address2>
<Postcode>12346</Postcode>
</CustAddress>
</CustAddresses>
<RecentContacts>
<RecentContact>
<ContDate>2011-04-12</ContDate>
<ContDesc>Enquiry</ContDesc>
</RecentContact>
<RecentContact>
<ContDate>2011-04-12</ContDate>
<ContDesc>Complaint</ContDesc>
</RecentContact>
<RecentContact>
<ContDate>2011-04-06</ContDate>
<ContDesc>Enquiry</ContDesc>
</RecentContact>
</RecentContacts>
<CustSummary>



I wish to extract this data into a single deep structure. I've declared the following models:



Ext.define('Customer', {
extend: 'Ext.data.Model',
fields: [
{name: 'ID' }
],
hasMany: [
{model: 'CustAddress', name: 'custAddresses' },
{model: 'Contact', name: 'recentContacts' }
],
proxy: {
type: 'ajax',
url: 'customers.xml',
reader: {
type: 'xml',
record: 'CustSummary'
}
}


Ext.define('CustAddress', {
extend: 'Ext.data.Model',
fields: [
{name: 'Name', mapping: 'CustAddresses > CustAddress > Name' },
{name: 'Address1' },
{name: 'Address2' },
{name: 'Postcode' }
],
belongsTo: 'Customer'
});


Ext.define('Contact', {
extend: 'Ext.data.Model',
fields: [
{name: 'ContDate', mapping: 'RecentContacts > RecentContact > ContDate' },
{name: 'ContDesc' }
],
belongsTo: 'Customer'
});


And finally I create the datastore:



var dataStore = Ext.create('Ext.data.Store', {
model: 'Customer'
});


dataStore.load();


However, the only data I can see in the store is the CustID, I can't see the RecentContacts or the CustAddresses structures (except in the Raw section of the object in the debugger). What am I doing wrong?

burnnat
10 Jul 2012, 1:25 PM
There were a variety of issues in getting this data to load, not least of which is that the provided data isn't even valid XML (mismatched tag names "CustomerSummary" and "CustSummary", with no closing tag). After fixing the XML, I was able to get it to work with a little bit of rearranging. Here's the set of model classes I used to load the data:


Ext.define('Address', {
extend: 'Ext.data.Model',
fields: ['Name', 'Address1', 'Address2', 'Postcode']
});

Ext.define('Contact', {
extend: 'Ext.data.Model',
fields: ['ContDate', 'ContDesc']
});

Ext.define('Customer', {
extend: 'Ext.data.Model',
fields: ['CustID'],
hasMany: [
{
model: 'Address',
name: 'addresses',
associationKey: 'CustAddresses',
reader: {
type: 'xml',
record: 'CustAddress'
}
},
{
model: 'Contact',
name: 'contacts',
associationKey: 'RecentContacts',
reader: {
type: 'xml',
record: 'RecentContact'
}
}
],
proxy: {
type: 'ajax',
url: 'customers.xml',
reader: {
type: 'xml',
record: 'CustSummary'
}
}
});

The "secret" here is to use the HasMany association's associationKey (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.association.Association-cfg-associationKey) and reader (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.association.Association-cfg-reader) configs. Hope that helps.

jratcliff
10 Jul 2012, 1:50 PM
@burnnat, I guess you and I were working on this at about the same time. :) Since you already mentioned the issues with the xml I'll leave that alone.

Here's the solution I came up with, which again, is basically the same as yours except I didn't use the associationKey and was just going to mention that as a way to allow you to specify your own 'name'. Otherwise, 'name' has to match the root xml node.



Ext.define('Customer', {
extend : 'Ext.data.Model',
fields : [
{ name : 'CustID' }
],
hasMany: [
{
model : 'CustAddress',
name : 'CustAddresses',
reader : {
type : 'xml',
record : 'CustAddress'
}
},
{
model : 'Contact',
name : 'RecentContacts',
reader : {
type : 'xml',
record : 'RecentContact'
}
}
],
proxy : {
type : 'ajax',
url : 'customers.xml',
reader : {
type : 'xml',
record : 'CustSummary'
}
}
});

Ext.define('Contact', {
extend : 'Ext.data.Model',
fields : [
{ name: 'ContDate' },
{ name: 'ContDesc' }
],
belongsTo : 'Customer'
});

Ext.define('CustAddress', {
extend : 'Ext.data.Model',
fields : [
{ name: 'Name' },
{ name: 'Address1' },
{ name: 'Address2' },
{ name: 'Postcode' }
],
belongsTo : 'Customer'
});

Ext.application({
name: 'Test',

launch: function () {

var dataStore = Ext.create('Ext.data.Store', {
model: 'Customer'
});

dataStore.on('load',function(store, records, success){
// let's examine the store
var arRecentContacts = records[0].RecentContacts(),
arCustAddresses = records[0].CustAddresses();

alert(arRecentContacts.data.length);
alert(arCustAddresses.data.length);
});

dataStore.load();
}
});

sencha_newb
23 Aug 2012, 3:07 AM
Hi guys,

Sorry about the delay; my email notifications were marked as spam. In any case the solutions mentioned here were correct, many thanks for the help!