Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-3174] iOS: Iterating Over XML Element Attributes

GitHub Issuen/a
TypeNew Feature
PriorityTrivial
StatusClosed
ResolutionWon't Fix
Resolution Date2011-11-29T15:45:58.000+0000
Affected Version/sRelease 1.7.0
Fix Version/sSprint 2011-47
ComponentsiOS
Labelsn/a
ReporterAnirudh Nagesh
AssigneeVishal Duggal
Created2011-04-15T03:38:49.000+0000
Updated2011-11-29T15:45:58.000+0000

Description

Problem

We can't iterate over attributes in a node. We can only access them by their name. We do expose the "attributes" property, which toStrings as a "[object TiDOMNamedNodeMap]". The length property of attributes correctly returns the number of attributes an element has, but there is no way to access an individual attribute by index (for example, node.attributes[0] is undefined).

Solution

Fix the attributes property to let you access each attribute by index, or expose a function to let you do this. The former approach would be more inline with major browsers.

Sample Code

The following sample code will write 'FAIL: some message' in a label if it isn't able to grab an attribute out of a simple XML string. Otherwise, it will write out the attribute name and value in a happy green color.

var win = Ti.UI.createWindow({ backgroundColor: '#fff' });
var label = Ti.UI.createLabel();
win.add(label);

label.color = '#f00';
label.text += 'FAIL: If you have time to read this, then we never finished reading the attributes.';

var dDocument = Titanium.XML.parseString('<?xml version="1.0" encoding="utf-8"?>\r\n<root foo="bar" />');
var node = dDocument.documentElement;
label.text = 'Found ' + node.attributes.length + ' attributes, ';
for (var i = 0; i < node.attributes.length; i++) {
    var attribute = node.attributes[i];
    if (attribute) {
        label.color = '#0f0';
        label.text += attribute.name + " = " + attribute.value;
    }
    else {
        label.color = '#f00';
        label.text += 'FAIL: attribute undefined.';
    }
}

win.open();

Tested On

Pulled from GitHub master last night: Titanium SDK version: 1.7.0 (02/17/11 20:28 316c2c7)
BROKEN on iPhone Simulator 4.2

Associated Helpdesk Ticket

http://developer.appcelerator.com/helpdesk/view/73221">http://developer.appcelerator.com/helpdesk/view/73221

Comments

  1. Jeroen K. 2011-04-15

    And what about .childNodes ?

  2. Anirudh Nagesh 2011-07-28

    Also, we cannot set the attribute value using setAttribute().

    Associated helpdesk ticket

    appc.me/c/APP-546582
  3. Dawson Toth 2011-08-22

    Changing reporter to Anirudh, as he bumped it to "Within Release" on the 19th of August.
  4. Blain Hamon 2011-10-17

    Changing this to a feature request. Turns out that the w3 DOM 2 spec does not specify usage of the attributes as an array. Furthermore, nodes do not have name nor value attributes. ( http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html ) Repeat: attributes[index], node.name, and node.value are all browser extensions and NOT part of the w3 spec. The w3 spec is attributes.item(index), node.nodeName, and node.nodeValue. After fixing the sample code to reflect this.
       var win = Ti.UI.createWindow({ backgroundColor: '#fff' });
       var label = Ti.UI.createLabel();
       win.add(label);
       
       label.color = '#f00';
       label.text += 'FAIL: If you have time to read this, then we never finished reading the attributes.';
       
       var dDocument = Titanium.XML.parseString('<?xml version="1.0" encoding="utf-8"?>\r\n<root foo="bar" />');
       var node = dDocument.documentElement;
       label.text = 'Found ' + node.attributes.length + ' attributes, ';
       for (var i = 0; i < node.attributes.length; i++) {
           var attribute = node.attributes.item(i);
           if (attribute) {
               label.color = '#0f0';
               label.text += attribute.nodeName + " = " + attribute.nodeValue;
           }
           else {
               label.color = '#f00';
               label.text += 'FAIL: attribute undefined.';
           }
       }
       
       win.open();
       
    The code ran fine. Changing this to a feature request to allow for the browser extension usage.
  5. Stephen Tramer 2011-11-29

    Not necessary. Here's the DOM2 IDL definition for NamedNodeMap: http://www.w3.org/TR/DOM-Level-2-Core/idl-definitions.html Instead, this can be done with the "length" attribute, and by calling the "item()" method to get the item at that index. NamedNodeMap objects should not behave like arrays.

JSON Source