PDA

View Full Version : XmlStore help on load XML not from url



AndreaCammarata
11 May 2011, 4:41 AM
Hi guys.
I need some help to load xml data inside an XmlStore, taking it not from an url, but from a simple variable placed in my XmlStore scope.
So suppose I have a simple xml variable defined like this:



var xml = '<users><user><id>1</id><name>Andrea</name></user></users>';
Is it possibile do ask to the store to fill itself reading the content of the xml variable?
(I used to work with Json data, but this time I really need XML)

Thank you guys.
I hope in your reply.

fay
11 May 2011, 6:17 AM
See: http://www.sencha.com/forum/showthread.php?54621-Using-local-XML-string-to-populate-Grid&p=260293&viewfull=1#post260293

So you can use something like:



function createXMLDoc(xmlString)
{
var xmlDocument;

if (Ext.isIE)
{
xmlDocument = new ActiveXObject("Microsoft.XMLDOM");
xmlDocument.async = "false";
xmlDocument.loadXML(xmlString);
}
else if (Ext.isGecko)
{
var parser = new DOMParser();
xmlDocument = parser.parseFromString(xmlString,"text/xml");
}
else
{
xmlDocument = null;
};

return xmlDocument;
};

Ext.onReady(function(){
var xml = '<users><user><id>1</id><name>Andrea</name></user></users>';

var store = new Ext.data.XmlStore({
record: 'user',
fields: ['id', 'name']
});
store.loadData(createXMLDoc(xml));

var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{header: "id", dataIndex: 'id', sortable: true},
{header: "name", dataIndex: 'name', sortable: true}
],
renderTo: Ext.getBody(),
width:540,
height:200
});
});

AndreaCammarata
11 May 2011, 7:01 AM
Hi fay.
Thank you a lot for your fast reply.
In the way you told me I'm able to load the xml document inside my store, but I have a little problem now:

I have adapted your function (really fast and in not an elegant way) to a Sencha Touch / Ext 4 code in this way:



Ext.setup({

onReady: function() {

var createXMLDoc = function(xmlString)
{
var parser = new DOMParser();
xmlDocument = parser.parseFromString(xmlString,"text/xml");

return xmlDocument;
};

Ext.regModel('User', {
fields: ['id', 'name']
});

var store = new Ext.data.Store({
model: 'User',
proxy: {
type: 'memory',
reader: {
type: 'xml',
record: 'user'
}
}
});

var xml = '<users><user><id>1</id><name>Andrea</name></user></users>';

store.loadData(createXMLDoc(xml));

}

});



At this poin, how I said, I'm able to load the XML doc in my store, but I can see, after loading, that it has 41 records! Most of them are "DomImplementation" or "Element" or null.

Do you have any idea why this happens?

Thank you again.

fay
11 May 2011, 7:42 AM
Ah, I didn't realise it was Ext JS 4. The following should work:



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>

<script type="text/javascript" src="../../bootstrap.js"></script>
<script type="text/javascript">

Ext.require([
'Ext.data.*',
]);

Ext.onReady(function() {

var createXMLDoc = function(xmlString)
{
var parser = new DOMParser();
var xmlDocument = parser.parseFromString(xmlString,"text/xml");
return xmlDocument;
};

// Set up a model to use in our Store
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
]
});

var xml = '<?xml version="1.0"?><users><user><id>1</id><name>Andrea</name></user><user><id>2</id><name>Fiachra</name></user></users>';

var store = new Ext.data.Store({
model: 'User',
data: createXMLDoc(xml),
proxy: {
type: 'memory',
reader: {
type: 'xml',
record: 'user'
}
}
});

console.log(store.getCount());
});
</script>
</head>
<body>
</body>
</html>


P.S. You're probably better off posting future questions in the Ext JS 4 Help Forum (http://www.sencha.com/forum/forumdisplay.php?81-Ext-Help).

AndreaCammarata
11 May 2011, 11:12 AM
Thank you again fay!
In this way I can see that has been stored 181 records (from my code).
But I still have a problem (I look two hours on other forum posts and tryed a lot of different ways but It doesn't work, I even play with DomQuery but nothing):

My xml has attribute like this:


<?xml version="1.0"?><list><users><user id="1" name="Andrea"></user><user id="2" name="Fiachra"></user></users></list>';
I tryed a LOT of mapping configuration in my store but anyone works.
Could you give me a hand on this?
Please consider the same example I already post with this different xml format.

Thank you a lot fay for your fast reply.

fay
11 May 2011, 11:32 AM
When using the attributes you need to add a mapping with the '@' character to your field definitions:


fields: [
{name: 'id', mapping: '@id', type: 'int'},
{name: 'name', mapping: '@name', type: 'string'}
]

Updated example:



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>

<script type="text/javascript" src="../../bootstrap.js"></script>
<script type="text/javascript">
Ext.require([
'Ext.data.*',
]);

Ext.onReady(function() {

var createXMLDoc = function(xmlString)
{
var parser = new DOMParser();
var xmlDocument = parser.parseFromString(xmlString,"text/xml");
return xmlDocument;
};

// Set up a model to use in our Store
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', mapping: '@id', type: 'int'},
{name: 'name', mapping: '@name', type: 'string'}
]
});

var xml = '<?xml version="1.0"?><users><user id="1" name="Andrea"></user><user id="2" name="Fiachra"></user></users>';

var store = new Ext.data.Store({
model: 'User',
data: createXMLDoc(xml),
proxy: {
type: 'memory',
reader: {
type: 'xml',
record: 'user'
}
}
});

console.log(store.getAt(0).get('name'));
});
</script>
</head>
<body>
</body>
</html>

AndreaCammarata
12 May 2011, 12:21 AM
Thank you gain for your reply fay, but this still not work, I already try this solution and a lot of other else.
Please notice that the store data is not loaded on store definition but I load it when I get if from the server in this way:



store.getProxy().data = createXMLDoc(xml);


But, I see my store with all the records I expect (181 total) but every record has empty fields values even with @field mapping.

Any idea why of this issue?
By now I adopted a less elagant solution making an Ext.each cycle on all the nodes, getting all the attributes I need, create a new record of User Data Model type, and load it into the store.
This works, but I would like to do it automatically with fields mapping when I load the store in the way you suggest me.

Thank you fay.

fay
12 May 2011, 12:33 AM
Could you post your XML as an attachment?

If you're getting it from your server, why bother going through the createXMLDoc route, and not just configure your store to load it directly? Is it part of some other response from your server?

To be honest, this is the first time I've used Ext JS 4 so I'm probably not the best to help out.

AndreaCammarata
12 May 2011, 12:48 AM
Sure!
The user xml was only an example but in my case I'm getting the response xml from a XMPP server after a lot of other calls to connect to it.
So, when I have to load the roaster items, I get an xml reply that is something like this.



<iq><query><item jid="[email protected]" name="Andrea Cammarata" subscription="both"><item jid="[email protected]" name="Mario Rossi" subscription="both"></item></query></iq>



So that's why I have to call the createXMLDoc when I got this reply and load it into my store.
To do this I configure my model in this way:



// Set up a model to use in our Store
Ext.define('Item', {
extend: 'Ext.data.Model',
fields: [
{name: 'jid', mapping: '@id', type: 'string'},
{name: 'name', mapping: '@name', type: 'string'},
{name: 'subscription', mapping: '@subscription', type: 'string'}
]
});


and my store in this way:



var store = new Ext.data.Store({
model: 'Item',
proxy: {
type: 'memory',
reader: {
type: 'xml',
record: 'item'
}
}
});



That's all!
I really tryed a lot of mapping configuration but nothing.
I think that if I discover how to get the item attributes with Ext.DomQuery I will be able to set the correct mapping.

fay
12 May 2011, 1:56 AM
Your XML looks fine, apart from a missing closing "</item>" in the first record.

As I said, I'm a complete newbie at Ext JS 4, but could you try the following... I think it should work for you, but I don't know why :)

At this stage, if it doesn't, I'm all out of ideas, and you'd probably be better off trying the Ext JS 4 Help Forum (http://www.sencha.com/forum/forumdisplay.php?81-Ext-Help).



store.getProxy().data = createXMLDoc(xml);

var op = new Ext.data.Operation({action: 'read'});
store.getProxy().read(op, function(){
store.loadData(op.getRecords(), false);

console.log(store.getCount());
if (store.getCount() > 0) {
console.log(store.getAt(0).get('name'));
}
});