PDA

View Full Version : XmlWriter: How to write XML attribute in request body



Seraith
16 Dec 2011, 3:34 PM
Hi,
I have a GridPanel with a store and an restful API.
The API produces "application/xml" and this works fine with the store/model.
It read the xml data and maps the attributes of the elements to the right fields.

What doesn't work is the writing from the store to the API.
The xml writer does a POST to the right url but the xml data in the request body is wrong.
All fields are now children of the elements instead of attributes.
well heres a sample of the request body
what i want is


<doc xml:id="" version="" baseProfile="" title="Hello World" alt="" longdesc="" class="" lang="" />
what i have is


<doc>
<xml:id></xml:id>
<version></version>
<baseProfile></baseProfile>
<title>Hello World</title>
<alt></alt>
<longdesc></longdesc>
<class></class>
<lang></lang>
</doc>

here the model with the rest proxy


Ext.define('TreeTest.model.Documents', {
extend: 'Ext.data.Model',
fields: [{
name: 'text',
type: 'string',
mapping: '@title'
}, {
name: 'version',
type: 'string',
mapping: '@version'
}, {
name: 'baseProfile',
type: 'string',
mapping: '@baseProfile'
}, {
name: 'id',
type: 'string',
mapping: '@id'
}, {
name: 'title',
type: 'string',
mapping: '@title'
}, {
name: 'alt',
type: 'string',
mapping: '@alt'
}, {
name: 'longdesc',
type: 'string',
mapping: '@longdesc'
}, {
name: 'class',
type: 'string',
mapping: '@class'
}, {
name: 'base',
type: 'string',
mapping: '@base'
}, {
name: 'lang',
type: 'string',
mapping: '@lang'
}],
idProperty: 'id',
proxy: {
type: 'rest',
idProperty: 'id',
extraParam: {
isXml: true
},
api: {
read: 'example/documents',
create: 'example/documents'
},
appendId: true,
reader: {
type: 'xml',
root: 'smils',
record: 'smil'
},
writer: {
type: 'xml'
// writeAllFields: true,
// documentRoot: 'docs'
// record: 'doc'
}
}
});

I also tried with the commented parts in the writer still the same result.
hopefully theres a solution for my problem..

mitchellsimoens
17 Dec 2011, 6:55 AM
That is how standard XML is done... as different nodes. You will need to dig into the XML writer to change it's behavior

dhreines
21 Dec 2011, 1:54 PM
We also need to integrate with legacy xml services that require XML attributes. Here's a potential change to the XmlWriter.writeRecords function that provides attributes. It tested out with our simple scenario. Let me know if anyone would have any concerns using this approach.




Ext.define('Ext.data.writer.Xml', {

...


writeRecords: function(request, data) {
var me = this,
xml = [],
i = 0,
len = data.length,
root = me.documentRoot,
record = me.record,
needsRoot = data.length !== 1,
item,
key,
attrs,
elements,
attrKey,
elemKey;


xml.push(me.header || '');


if (!root && needsRoot) {
root = me.defaultDocumentRoot;
}


if (root) {
xml.push('<', root, '>');
}


for (; i < len; ++i) {
item = data[i];
attrs = [];
elements = [];
for (key in item) {
if (item.hasOwnProperty(key)) {
if (key.charAt(0) == '@') {
attrs[key] = item[key];
} else {
elements[key] = item[key];
}
}
}
xml.push('<', record);
for (attrKey in attrs) {
xml.push(' ', attrKey.substring(1,attrKey.length), '="', attrs[attrKey], '"');
}
xml.push('>');
for (elemKey in elements) {
xml.push('<', elemKey, '>', elements[elemKey], '</', elemKey, '>');
}
xml.push('</', record, '>');
}


if (root) {
xml.push('</', root, '>');
}


request.xmlData = xml.join('');
return request;
}