PDA

View Full Version : Problems reading some (not all) data in XML



SamTass
18 Jul 2011, 5:27 AM
Hi guys if anyone can help me with this i'd be greatful.
Having a couple of issues reading my XML, I managed to get this working just fine in jQuery and what not but in Sencha I'm struggling to find my way around.
All I need to to is read all the 'product' values really, it's outputting the right amount but not giving me the values, I've tried multiple versions but still get the same issue, not sure whether I need something similar like .innerText etc..?
Anyways if you could have a gander below and let me know what you think that would be great.

Here is the JS etc...

<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Product Test</title>
<script src="../sencha-touch-debug.js" type="text/javascript">
</script>
<link href="../resources/css/sencha-touch.css" rel="stylesheet" type="text/css">
<script type="text/javascript">
new Ext.Application({
name: 'Products',
launch: function(){

Ext.regModel('Products', {
fields: ['warehouse', 'location', 'products'],
associations: [{type: 'hasMany', model: 'Friend', name: 'products'}]

});
Ext.regModel('Friend', {
fields: ['product'],
belongsTo: 'Products',
proxy: {
type:'ajax',
reader: {
type: 'xml',
root: 'products',
record: 'product'
}
}
});
this.stores.profiles = new Ext.data.Store({
model: 'Products',
autoLoad:true,
implicitIncludes: true,
proxy: {
type: 'ajax',
url : 'products.xml',
reader: {
type : 'xml',
root : 'productList',
record: 'productList'
}
}
});
var productTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="product-ean">Warehouse: {warehouse} </div>',
'<div class="product-ean">Location: {location} </div>',
'<tpl for="products">',
'<div class="product-ean">Product: {product} </div>',
'</tpl>',
'</tpl>'
);
new Ext.Panel({
fullscreen: true,
items: new Ext.DataView({
store: this.stores.profiles,
tpl: productTpl,
itemSelector: 'product-selected'
//other config goes here
})
});
}
});
</script>
</head>
<body>
</body>
</html>Here is the XML:

<?xml version="1.0" encoding="utf-8"?>
<productList>
<warehouse>Warehouse A</warehouse>
<location>Warwickshire</location>
<products>
<product>0231564</product>
<product>4756456</product>
<product>1237453</product>
<product>1235878</product>
<product>1594454</product>
<product>7898456</product>
</products>
</productList>
And here is the result I get:

Warehouse: Warehouse A
Location: Warwickshire
Product:
Product:
Product:
Product:
Product:
Product:Basically it's returning the right amount but can't seem to get the data, i've tried '{.}' etc...
The aim with this will be to get all the product codes then run a seperate ajax request to use the code in all XML url, but that comes later.

Thanks in advance.
Sam Tassell.

jratcliff
18 Jul 2011, 6:55 AM
Use this override and change your product to map to '$self'.


This override just allows '$self' to be passed in as the key and when it sees that, the DomQuery.selectNode call is skipped and the root is returned as the node.



Ext.override(Ext.data.XmlReader, {

createAccessor: function() {
var selectValue = function(key, root, defaultValue){
//var node = Ext.DomQuery.selectNode(key, root),
var node = (key === '$self') ? root : Ext.DomQuery.selectNode(key, root),
val;
if (node && node.firstChild) {
val = node.firstChild.nodeValue;
}
return Ext.isEmpty(val) ? defaultValue : val;
};

return function(key) {
var fn;

if (key == this.totalProperty) {
fn = function(root, defaultValue) {
var value = selectValue(key, root, defaultValue);
return parseFloat(value);
};
}

else if (key == this.successProperty) {
fn = function(root, defaultValue) {
var value = selectValue(key, root, true);
return (value !== false && value !== 'false');
};
}

else {
fn = function(root, defaultValue) {
return selectValue(key, root, defaultValue);
};
}

return fn;
};
}()

});



For your product field, change it to map to '$self'


fields: [{
name: 'product',
mapping: '$self'
}],

SamTass
18 Jul 2011, 12:38 PM
Thank you for your quick reply your solution works perfectly, although I can't really get my head around code but I'm sure I will in time. The only other thing I wanted it ask which is related to this is the point I made about using the profile values in more XML requests. For example shown below is a rather cack handed way I did this in jQuery/JS, please accuse the bad coding and random notes:


$(document).ready(function(){

$.ajax({
type: "GET",
url: "products.xml",
dataType: "xml",

success: function(xml) {
$(xml).find('products').each(function(){

//var pageArray = new Array();

var products = $(this).find('product')

//for ( var i = 0; i < 0; i++ )(function(i){
for ( var i = 0; i < products.length; i++ )(function(i){

(function( ){ //anonymous function for scope

var index = i; // The important part!

// On-Line Image Animations
var containertoggle = [];
var extrainfotoggle = [];
// It's not technically necessary to use 'index' here, but for good measure...
containertoggle[index] = 'containertoggle' + index;
extrainfotoggle[index] = 'extrainfo' + index;

var profileid = $(profiles[i]);

$.ajax({
type: "GET",
url: "http://www.URLHERE.com/"+profileid.text()+"?xml=1",
dataType: "xml",
success: function(xml) {

$(xml).find('profile').each(function(){

var profilenumber = i;
var example = $(this).find('example:first').text();

// etc etc...

var html = '<div id="container" class="'+somevariable+'">';

html += '<div class="'+somevariable[index]+'"'+somevariable+'>';
//html += gameicon;
html += '<div id="containerinner">';
html += '<div id="avatar"'+somevariable+' style="background-image:url('+somevariable+')"></div>';
html += '<div id="data">';
html += '<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="middle">';
html += somevariable;
html += '</td></tr></table>';
html += '</div>';
html += '<div style="clear:both"></div>';
html += '</div>';
html += '<div style="clear:both"></div>';
html += '</div>';
html += '<div class="'+somevariable[index]+'" style="overflow:hidden;height:0px;border-left:'+somevariable+';border-right:'+somevariable+';">'+somevariable+'</div>';
html += '<div style="clear:both"></div>';
html += '</div>';

$('#page-wrap').append($(html));


//WAIT UNTIL CONTENT IS LOADED!!
if (i == 8 - 1){
//if (i == friends.length - 1){
$("#loader").hide();
$(".onload").show();
var fre = 1;
}//WAIT UNTIL CONTENT IS LOADED END
//Extra info toggling
$("."+containertoggle[index]).toggle(
function(){
$("."+extrainfotoggle[index]).animate({
height: "51px"
}, 250 );
},
function(){
$("."+extrainfotoggle[index]).animate({
height: "0px"
}, 250 );

}); //.toggle END

}); //$(xml).find('profile') END

} //function(xml) END

});//$.ajax END jQuery('#loadingimage').fadeOut(300);

})(); // end anonymous function and execute

})(i);//for ( var i = 0; i < 8; i++ ) END

}); //$(xml).find('friends') END.delay(800)

}//function(xml) END

});//$.ajax END

});//$(document).ready ENDHopefully you can see the kind of thing I'm trying to accomplish, I did strip a load out due to the length. Basically using one XML result, somehow store the values then use them within other requests. The end result will basically be a list view returning each result where by I can access the data freely.

So from the original XML I will take the 'product ID', then for each 'product ID' do a seperate XML request/read and have it in a format where by I can display all my data is list form.

Quite hard to explain really :). :-?

If you can help in any way it's much appreciated.

Sam Tassell.