Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-8953] Android: XML: Erratic Namespace Definition and Redefinition

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2012-05-18T21:12:40.000+0000
Affected Version/sRelease 2.0.1
Fix Version/sRelease 2.0.2, Release 2.1.0, Sprint 2012-10 API
ComponentsAndroid
Labelsapi, module_xml, qe-testadded
ReporterDawson Toth
AssigneeJosh Roesslein
Created2012-05-02T12:09:21.000+0000
Updated2012-07-05T15:02:57.000+0000

Description

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".

Comments

  1. Dawson Toth 2012-05-02

    Not ready to create this ticket.
  2. Dawson Toth 2012-05-07

    Ready to make this ticket now. Will take a bit to update it, hold tight...
  3. Dawson Toth 2012-05-07

    Updated. Ready for escalation.
  4. Josh Roesslein 2012-05-18

    With the new fix change line 44 to:
       var actual = ((Ti && Ti.XML) || new XMLSerializer()).serializeToString(feed);
       
    We now properly output the XML declaration so no need to append this onto the result.
  5. Josh Roesslein 2012-05-18

    Pull request [#2225](https://github.com/appcelerator/titanium_mobile/pull/2225) is up.
  6. Natalie Huynh 2012-05-23

    Tested with 2.0.2.v20120522180515 on Samsung Galaxy 4.0.4

JSON Source