Problem
There are a couple bugs preventing proper XML generation in Titanium. These are demonstrated in the reproduction below.
1. Defining a namespace attribute for a document element ends up redefining "xmlns", which kills most XML interpreters because it's an illegal redefinition. (For example, I want to add an xmlns:m attribute to my doc, but it ends up redefining xmlns:n0="
http://www.w3.org/2000/xmlns/" and adding n0:m="myurl".)
2. Prefix names are ignored. In the example, "atom:" is renamed to "n0:", "xmlns:" to "n1:", "d:" to "n2:", and "m:" to "n3".
3. Existing namespace definitions are ignored, in favor of defining the namespace on every child that specifies it. This shows up in the example for the properties and message elements receiving the new prefix "n2" and "n3", respectively.
Reproduction
(function (document, Ti) {
document = document || Ti && Ti.XML.parseString('<a/>');
var feed = document.implementation.createDocument('http://www.w3.org/2005/Atom', 'atom:feed', null);
feed.documentElement.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:atom', 'http://www.w3.org/2005/Atom');
feed.documentElement.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:m', 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
feed.documentElement.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:d', 'http://schemas.microsoft.com/ado/2007/08/dataservices');
var id = feed.documentElement.ownerDocument.createElementNS('http://www.w3.org/2005/Atom', 'atom:id');
id.appendChild(feed.documentElement.ownerDocument.createTextNode('http://appc.me/odata/flocker/4f9f037df04d4613dc0607d7'));
feed.documentElement.appendChild(id);
var title = feed.documentElement.ownerDocument.createElementNS('http://www.w3.org/2005/Atom', 'atom:title');
title.appendChild(feed.documentElement.ownerDocument.createTextNode('4f9f037df04d4613dc0607d7'));
feed.documentElement.appendChild(title);
var entry = feed.documentElement.ownerDocument.createElementNS('http://www.w3.org/2005/Atom', 'atom:entry');
var content = feed.documentElement.ownerDocument.createElementNS('http://www.w3.org/2005/Atom', 'atom:content');
content.setAttribute('type', 'application/xml');
var properties = feed.documentElement.ownerDocument.createElementNS('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata', 'm:properties');
var message = feed.documentElement.ownerDocument.createElementNS('http://schemas.microsoft.com/ado/2007/08/dataservices', 'd:message');
message.appendChild(feed.documentElement.ownerDocument.createTextNode('This is a flock!'));
properties.appendChild(message);
content.appendChild(properties);
entry.appendChild(content);
feed.documentElement.appendChild(entry);
var expected = '<?xml version="1.0" encoding="UTF-8"?>\
<atom:feed xmlns:atom="http://www.w3.org/2005/Atom"\
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"\
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">\
<atom:id>http://appc.me/odata/flocker/4f9f037df04d4613dc0607d7</atom:id>\
<atom:title>4f9f037df04d4613dc0607d7</atom:title>\
<atom:entry>\
<atom:content type="application/xml">\
<m:properties>\
<d:message>This is a flock!</d:message>\
</m:properties>\
</atom:content>\
</atom:entry>\
</atom:feed>'.replace(/\s{1,}/ig, ' ').replace(/> </ig, '><');
var actual = '<?xml version="1.0" encoding="UTF-8"?>' + ((Ti && Ti.XML) || new XMLSerializer()).serializeToString(feed);
if (Ti) {
Ti.API.info('Expected:\n' + expected);
Ti.API.info('Actual:\n' + actual);
}
else {
console.log('Expected:\n' + expected);
console.log('Actual:\n' + actual);
}
if (expected != actual) {
alert('FAIL! Check logs for more information.');
}
else {
alert('PASS!');
}
})(this['document'], this['Ti']);
Test Results
Chrome
**PASS**
The expected and actual are equal.
Android Galaxy Tab 7.0+ (3.2)
**FAIL**
The actual results are as follows (once problem #1 is resolved):
<?xml version="1.0" encoding="UTF-8"?>
<n0:feed n1:atom="http://www.w3.org/2005/Atom" n1:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
n1:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:n0="http://www.w3.org/2005/Atom"
xmlns:n1="http://www.w3.org/2000/xmlns/">
<n0:id>http://appc.me/odata/flocker/4f9f037df04d4613dc0607d7</n0:id>
<n0:title>4f9f037df04d4613dc0607d7</n0:title>
<n0:entry>
<n0:content type="application/xml">
<n2:properties xmlns:n2="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<n3:message xmlns:n3="http://schemas.microsoft.com/ado/2007/08/dataservices">This is a flock!
</n3:message>
</n2:properties>
</n0:content>
</n0:entry>
</n0:feed>
Note these discrepancies:
1. "xmlns" prefix renamed to "n1".
2. "atom" prefix renamed to "n0".
3. Explicit definition of "xmlns" as "xmlns:n1".
4. With explicit "n1" definition, "d" and "m" namespaces are placed under "n1:" instead of "xmlns:".
5. Disregarding "d:" and "m:" in favor of redefining the new namespaces "n2" and "n3" for "n2:properties" and "n3:message". Should be "m:properties" and "d:properties".
Not ready to create this ticket.
Ready to make this ticket now. Will take a bit to update it, hold tight...
Updated. Ready for escalation.
With the new fix change line 44 to:
We now properly output the XML declaration so no need to append this onto the result.
Pull request [#2225](https://github.com/appcelerator/titanium_mobile/pull/2225) is up.
Tested with 2.0.2.v20120522180515 on Samsung Galaxy 4.0.4