Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-8952] iOS XML: appendChild Removes Namespace and Over Validation

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2012-05-03T16:45:14.000+0000
Affected Version/sRelease 2.0.1
Fix Version/sRelease 2.0.2, Release 2.1.0, Sprint 2012-09 API
ComponentsiOS
Labelsapi, qe-port
ReporterDawson Toth
AssigneeVishal Duggal
Created2012-05-02T12:08:45.000+0000
Updated2012-05-14T20:48:13.000+0000

Description

Problem

There are several problems preventing proper XML generation in Titanium: 1. When an element is appendChild'd to a parent on iOS, it loses its namespace. This is exhibited in all of the elements, other than "feed", below. Plus, an extra xmlns:xmlns attribute is added to "feed". 2. "xmlns" cannot be used in an attribute NS. Browsers don't impose this restriction. Why do we? It is preventing me from defining a namespace. This blocking problem can be worked around by removing lines 26-27 and 42-43 of TiDOMValidator.m.

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 = document.createElementNS('http://www.w3.org/2005/Atom', 'atom:id');
    id.appendChild(document.createTextNode('http://appc.me/odata/flocker/4f9f037df04d4613dc0607d7'));
    feed.documentElement.appendChild(id);

    var title = document.createElementNS('http://www.w3.org/2005/Atom', 'atom:title');
    title.appendChild(document.createTextNode('4f9f037df04d4613dc0607d7'));
    feed.documentElement.appendChild(title);

    var entry = document.createElementNS('http://www.w3.org/2005/Atom', 'atom:entry');
    var content = document.createElementNS('http://www.w3.org/2005/Atom', 'atom:content');
    content.setAttribute('type', 'application/xml');
    var properties = document.createElementNS('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata', 'm:properties');

    var message = document.createElementNS('http://schemas.microsoft.com/ado/2007/08/dataservices', 'd:message');
    message.appendChild(document.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, Firefox, Safari

**PASS** The expected and actual are equal.

iPhone Simulator 5.1

**FAIL** The actual results are as follows (once problem #1 is resolved): ``` http://www.w3.org/2000/xmlns/" 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">http://appc.me/odata/flocker/4f9f037df04d4613dc0607d74f9f037df04d4613dc0607d7This is a flock! {quote} Note these discrepancies: 1. Extra xmlns:xmlns attribute on "feed". 2. "properties" has lost its prefix. 3. "message" has lots its prefix. 4. "id", "title" have lost their prefix.

Comments

  1. Dawson Toth 2012-05-03

    Adjusted. Chrome was being graceful and working properly despite me doing the XML generation... poorly. The above code should now be an accurate reflection of something that works in modern browsers, and should work in Titanium as well.
  2. Vishal Duggal 2012-05-03

    Pull pending https://github.com/appcelerator/titanium_mobile/pull/2134
  3. Natalie Huynh 2012-05-14

    Tested with 2.0.2.v20120514121649 with iPhone Simulator 5 and iPhone 4 5.0.1 (When testing on the device: add this code: var win = Ti.UI.createWindow(); or it will fail to build because there is no window in the code)

JSON Source