Archive for the ‘xml’ tag
XML Constants Gotcha
In my head, XML slips between the cracks of being an Object and a primitive type. It shouldn’t, and when I’m concentrated it doesn’t. But still, there is something primitive-type about it.
private const DATA:XML = <data message="Hello World!" />;
and
private const DATA:String = "Hello World!";
are intuitively the same sorts of things. XML is like an advanced sort of String. We encode it as we encode text, and we convert it to and from Strings without difficulty. I don’t construct XML, at least it doesn’t feel like I do. In my preferred coding environment (FDT) by default they’re even similarly coloured.
However, they are clearly not the same, because XML is mutable:
DATA.@message = "This message has been changed!";
Needless to say, that doesn’t work on a String! Somehow by labelling the XML a ‘constant’ I expect the XML to be immutable.
On reflection I know this about XML, but it feels wrong. This ‘gotcha’ does not identify a language bug, but suggests a mental corrective: when you think about XML, make sure that you don’t mistake it for a primitive type. When I’m not concentrating I do, and it occassionally trips me up.
XML Gotcha – new XML(null)
Without trying it, how would you expect this to behave?
var xml:XML = new XML(null);
Personally I don’t think that constructing XML from a null object should work, but it does. I would have expected an error, like if I try to do this:
var xml:XML = new XML("<bad>hello world</tags>");
That’s about as clear a case of error throwing as you can get, I think. Why not for null?
It turns out that null is interpreted as a sort of weird XML singularity. It has one node which has no name, to which you can add attributes and children. However much you add, always the length is 1 and the toXMLString() is an empty string. Happily, this latter fact can save you from being consumed by the singularity: you can test for it by checking whether
xml.toXMLString() == "";
and take appropriate steps if it does!
I haven’t thought through all the consequences of this behaviour but it took me completely by surprise… if you can explain to me why Adobe considered this the preferred behaviour, please let me know! This is another of those hard-to-spot XML bugs like this one I found earlier. Someone, preferably Simone since he’s already on it, should wrap fixes for this stuff into a helper class!
Update
var xml:XML = new XML(null);
is – of course – the same as
var xml:XML = new XML();
The documentation doesn’t indicate that you can pass an empty value into the XML constructor, but as my colleague Simone pointed out, playerglobal.swc indicates that you can. The documentation meanwhile says that the constructor parameter for an XML object should be
Any object that can be converted to XML with the top-level XML() function.
and the top-level XML function documentation states that if you pass a null into it:
null: A runtime error occurs (TypeError exception).
However, that doesn’t throw an error either!
I started this update having seen the playerglobal.swc definition about to eat some humble pie, but this further investigation has served to strengthen my understanding of how weird this behaviour is. Be warned, this stuff is out there waiting to spoil your afternoon’s coding!
