PDA

View Full Version : Bug in XMLWriter or at the very least a massive limitation on it's usability



GregoryC
5 Jan 2011, 2:51 AM
Hello,

I have configured an XMLWriter, for the XMLStore described below, based on an example from the website.

I was delighted to see that field data can be retrieved from attributes (color) and indeed from grandchild element (imageUrl) and it all displays nicely and allows edits.

However, when I try to write the xml back to the server, it produces garbage. Obviously it is assuming that fields only exist as the text of child element and it attempts to reconstruct the file, producing something like.

<?xml version="1.0" encoding="ISO-8859-15"?><Product><Name>Widgets</Name><Price>11.95</Price><ImageData > Url>widget.png</ImageData > Url><@color>Red</@color></Product>

I suspect a fundamental rethink of how the xml writer is implemented would need to be considered here. The XMLReader has a copy of the original XML file. Instead of attempting to reproduce the xml from scratch, the changes need to be applied to the original xml file according to the mappings of the store, i.e. retrieve the element at "ImageData > Url", and update the value. Then post the modified XML back to the server.

This would also resolve my second issue here, which is that any data in the source xml file, which is not mapped into the XMLStore is currently lost. How is the server backend supposed to know if that data was intentionally removed in the front end, and should be removed in the back end? It really does not make sense to me, that every little piece of an xml file needs to be mapped into a store, even if I am not going to use it in the UI.

ProductStore = Ext.extend(Ext.data.XmlStore, {
constructor: function(cfg) {
cfg = cfg || {};
ProductStore.superclass.constructor.call(this, Ext.apply({
storeId: 'ProductStore',
url: 'cars/products.xml',
record: 'Product',
autoLoad: true,
fields: [
{
name: 'name',
mapping: 'Name'
},
{
name: 'price',
mapping: 'Price'
},
{
name: 'imageUrl',
mapping: 'ImageData > Url'
},
{
name: 'color',
mapping: '@color'
}
]
}, cfg));
}
});
Ext.reg('ProductStore', ProductStore);

Condor
5 Jan 2011, 4:10 AM
XmlWriter can only write basic unnested XML data.

If you need to render anything more complex then you will need to specficy your own 'tpl'.

In your case:

tpl: '<tpl for=".">' +
'<\u003fxml version="{version}" encoding="{encoding}"\u003f>' +
'<tpl if="records.length&gt;1">' +
'<{root}>' +
'</tpl>' +
'<tpl for="records">' +
'<Product color="{color}">' +
'<Name>{name}</Name>' +
'<Price>{price}</Price>' +
'<ImageData>' +
'<Url>{imageUrl}</Url>' +
'</ImageData>' +
'</Product>' +
'</tpl>' +
'<tpl if="records.length&gt;1">' +
'</{root}>' +
'</tpl>' +
'</tpl>'

Or if you need a documentRoot and/or baseParams:

tpl: '<tpl for=".">' +
'<\u003fxml version="{version}" encoding="{encoding}"\u003f>' +
'<tpl if="documentRoot">' +
'<{documentRoot}>' +
'<tpl for="baseParams">' +
'<tpl for=".">' +
'<{name}>{value}</{name}>' +
'</tpl>' +
'</tpl>' +
'</tpl>' +
'<tpl if="records.length&gt;1">' +
'<{root}>' +
'</tpl>' +
'<tpl for="records">' +
'<Product color="{color}">' +
'<Name>{name}</Name>' +
'<Price>{price}</Price>' +
'<ImageData>' +
'<Url>{imageUrl}</Url>' +
'</ImageData>' +
'</Product>' +
'</tpl>' +
'<tpl if="records.length&gt;1">' +
'</{root}>' +
'</tpl>' +
'<tpl if="documentRoot">' +
'</{documentRoot}>' +
'</tpl>' +
'</tpl>'

GregoryC
5 Jan 2011, 5:29 AM
Thanks for the speedy reply, greatly appreciated!

I will not be able to achieve what I need with such a solution, but it is really good to know how it is intended to work.

Kind Regards,
Greg