Not yet rated

Problem

I need to collect some values by names and namespaces

Solution

I have created some special collections/objects based on flash.utils.Proxy that can store dynamic properties in custom namespaces

Detailed explanation

If you will face such problem , what you will do first? I have checked ordinary Object for this feature:

var ns:Namespace = new Namespace(null, 'urn:uri-custom-namespace');
var name:QName = new QName(ns, 'localName');
var object:Object = {};
try{
    object.ns::localName = 'value';
}catch(error:Error){
    trace(error.message); // Error #1056: Cannot create property urn:uri-custom-namespace::localName on Object.
}
try{
    object[name] = 'value';
}catch(error:Error){
    trace(error.message); // Error #1056: Cannot create property urn:uri-custom-namespace::localName on Object.
}


Nope, no deal with Object, let's try next pretender - fancy flash.utils.Dictionary, because it can contain keys of ANY type (no restrictions in docs):

var ns:Namespace = new Namespace(null, 'urn:uri-custom-namespace');
var name:QName = new QName(ns, 'localName');
var dictionary:Dictionary = new Dictionary();
try{
    dictionary[name] = 'value';
}catch(error:Error){
    trace(error.message); // Error #1056: Cannot create property urn:uri-custom-namespace::localName on flash.utils.Dictionary.
}


Funny, nothing about this restriction on the docs. Next? XML!

var ns:Namespace = new Namespace(null, 'urn:uri-custom-namespace');
var name:QName = new QName(ns, 'localName');
var xml:XML = <root/>;
try{
    xml[name] = 'value';
}catch(error:Error){
    trace(error.message); //
}
trace(xml[name]); // value
trace(getQualifiedClassName(xml[name])); // XMLList
trace(xml[name][0].toXMLString()); // <localName xmlns="urn:uri-custom-namespace">value</localName>


Looks like it works, but something wrong… Ah, yes - value not the same, now it is a XML node with name "localName" in "urn:uri-custom-namespace" namespace. For primitives it will work, but nothing bigger. Have I missed something else?
I need hundred percent support, and I have created one.

var ns:Namespace = new Namespace(null, 'urn:uri-custom-namespace');
var name:QName = new QName(ns, 'localName');
var names:XMLNameDynamicCollection = new XMLNameDynamicCollection(false, true);
try{
    names[name] = 'value';
}catch(error:Error){
    trace(error.message); //
}
trace(names[name]); // value
trace(getQualifiedClassName(names[name])); // String
try{
    names[name] = new Sprite();
}catch(error:Error){
    trace(error.message); //
}
trace(names[name]); // [object Sprite]
trace(getQualifiedClassName(names[name])); // flash.display::Sprite
names.ns::shape = new Shape();
names.ns::simpleButton = new SimpleButton();
names.ns::movieClip = new MovieClip();
names.ns::xml = <xml/>;
for(var itemName:String in names){
    trace(' --', itemName, getQualifiedClassName(names[itemName]));
}
/*
-- urn:uri-custom-namespace::localName flash.display::Sprite
-- urn:uri-custom-namespace::shape flash.display::Shape
-- urn:uri-custom-namespace::xml XML
-- urn:uri-custom-namespace::movieClip flash.display::MovieClip
-- urn:uri-custom-namespace::simpleButton flash.display::SimpleButton
*/


This looks like truth. In attachment you will find four core classes. XMLNameCollection and QNameCollection is just collections, which have methods:

  *     callProperty - call method by name

  *     getProperty - get property value by name

  *     hasProperty - check property

  *     deleteProperty - delete property

  *     setProperty -set property value

The difference between XMLCollection and QNameCollection is QNameCollection can accept attributes, but XMLCollection will ignore. As you have seen, I've used XMLNameDynamicCollection in example, not just XMLNameCollection. XMLNameCollection and QNameCollection have dynamic wrappers - XMLNameDynamicCollection and QNameDynamicCollection, that extended from flash.utils.Proxy and this wrappers can store dynamic properties. Each wrapper contains collection inside. Both wrappers accept only two arguments in constructor:

  1.     if TRUE, will save each property name in separated vector and will use it for cycles

  2.     flash.utils.Proxy can return only String as property name if you using for…in cycle(there is a bug, I have added an issue). And this key enables auto-parsing of String keys with "::" in value. If this key is TRUE and you will pass string like "anything-here1:: anything-here2" into wrapper, it will convert this string into QName instance with namespace "anything-here" and local name "anything-here2".

QNameCollections.zip
[QName and XMLName collections and wrappers]

+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes