PDA

View Full Version : How to read xml with Ext.data.XmlReader?



yanasdf789
21 Jan 2011, 8:35 PM
How to read xml with Ext.data.XmlReader?my XML like this


<Items>
<topic >
<ASIN>0446354732</ASIN>
<Topinfo>
<Author>Sidney Sheldon</Author>
<Neirong>Warner Books</Neirong>
<riqi>Book</riqi>
<Num>Nothing Lasts Forever</Num>

</Topinfo>
<reply>
<Author>yanli1</Author>
<data>2010</data>
<contentt>ok</contentt>
</reply>
<reply>
<Author>yanli2</Author>
<data>2012</data>
<contentt>love</contentt>
</reply>

</topic>

<topic >
<ASIN>06354732</ASIN>
<Topinfo>
<Author>Sidney Sheldon</Author>
<Neirong>Warner Books</Neirong>
<riqi>Book</riqi>
<Num>Nothing Lasts Forever</Num>

</Topinfo>
</topic>

</Items>


i want to read the data < reply >of the <topic >with "<ASIN>0446354732</ASIN>

Condor
22 Jan 2011, 3:22 AM
That would be:

record: 'topic:has(> ASIN:contains(0446354732)) > reply'
but I don't think you can nest pseudos, so you'll have to use:

record: 'topic:contains(0446354732) > reply'
which isn't specific enough, so it could produce false positives.

Nicolas BUI
4 Feb 2011, 2:07 AM
with the actual XmlReader, you have to do so :


var store = new Ext.data.XmlStore({
url: "your url",
record: 'topic'
fields: [
'ASIN',
{ name: 'InfoAuthor', mapping: 'Topinfo/Author'},
{ name: 'InfoNeirong', mapping: 'Topinfo/Neirong'}
'reply'
]
});


Tthis will not work, because "reply" field will not be an array of the replies, but a string instead.
This is due to the XmlReader as it try to read the node value. In the source of XmlReader,
You will see the call of "q.selectValue(key, root, def)", you will get a string.

So if you can get the nodes "reply" it would be nice, huh ? But don't expect to use XTemplate because it play nice with JSON only.

So to resolve this, I've extended XmlReader and XmlStore, and override the "createAccessor" method to transform a node to json data if possible.
I simply check a simple condition : I'll return json if the node contains child nodes. otherwise the value is use as default.

Here is the code I've ends with, hope it will help you a bit:



Ext.ux.data.XmlReader = Ext.extend(Ext.data.XmlReader, {
constructor: function(meta, recordType) {
Ext.ux.data.XmlReader.superclass.constructor.call(this, meta, recordType);
},

countChildrens : function(node) {
var res = 0;
if (node && node.nodeType === 1 && node.childNodes.length > 0) {
for (var step = 0, len = node.childNodes.length; step < len; step++) {
var child = node.childNodes[step];
if (child.nodeType !== 3) {
res++;
}
}
}
return res;
},

toJson : function(node) {
var res = {};
if (node && Ext.ux.data.XmlReader.prototype.countChildrens(node) > 0) {
for (var step = 0, len = node.childNodes.length; step < len; step++) {
var child = node.childNodes[step];
var type = child.nodeType;
var name = child.nodeName;
if (type !== 3) {
if (name in res) {
if (!Ext.isArray(res[name])) {
var tmp = res[name];
res[name] = [];
res[name].push(tmp);
}
res[name].push(Ext.ux.data.XmlReader.prototype.toJson(child));
}
else {
res[name] = Ext.ux.data.XmlReader.prototype.toJson(child);
}
}
}
}
else if (node.childNodes.length == 1 && node.childNodes[0].nodeType === 3) {
res = node.childNodes[0].textContent;
}
return res;
},

createAccessor : function() {
var q = Ext.DomQuery;
return function(key) {
if (Ext.isFunction(key)) {
return key;
}
switch (key) {
case this.meta.totalProperty:
return function(root, def) {
return q.selectNumber(key, root, def);
};
break;
case this.meta.successProperty:
return function(root, def) {
var sv = q.selectValue(key, root, true);
var success = sv !== false && sv !== 'false';
return success;
};
break;
default:
return function(root, def) {
var node = q.selectNode(key, root, def);
var value = q.selectValue(key, root, def);
if (Ext.ux.data.XmlReader.prototype.countChildrens(node) > 0) {
return Ext.ux.data.XmlReader.prototype.toJson(node);
}
return value;
};
break;
}
};
}()
});




Ext.ux.data.XmlStore = Ext.extend(Ext.data.Store, {
constructor: function(config)
{
Ext.ux.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
reader: new Ext.ux.data.XmlReader(config)
}));
}
});