Flex:Actionscript:E4X – Bug in implicit xml namespace handling

Just posted the following bug report to the adobe bugs site.

Steps to reproduce:
Construct an XML variable with no explicit namespaces and any xml: attribute such as xml:lang or xml:id. E4X will correctly construct an implicit namespace for xml:, but will not assign the xml prefix to it, as such you end up with a default namespace which now applies to anything in your XML that doesn’t explicitly have another namespace associated with it.

Here’s a sample flex app that demonstrates the issue.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
private function init():void
{
var x:XML = <root xml:lang="en"><element/></root>
ta.text = x.toXMLString();
}
]]>
</mx:Script>
<mx:TextArea id="ta" width="100%" height="100%"/>
</mx:Application>

Actual Results:

<root lang="en" xmlns="http://www.w3.org/XML/1998/namespace">
<element/>
</root>

Notice that the root and element elements now incorrectly exist in the http://www.w3.org/XML/1998/namespace namespace.

Expected Results:

<root someprefix:lang="en" xmlns:someprefix="http://www.w3.org/XML/1998/namespace">
<element/>
</root>

Where someprefix is probably xml…

Workaround (if any):

  • The xml:lang element was being added by our XML database and is not actually used by our app, so we simply removed it.
  • You can specify xmlns:xml=”http://www.w3.org/XML/1998/namespace&#8221; in the root element and then the correct prefix is applied.

Bug in how Flex handles Tree data binding

We discovered a couple of very strange bugs in how Flex trees handle data binding today. Our tree has showRoot=”false”. We are using e4x to bind to a sub-element of some source XML. Here is a sample MXML file:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; layout=”vertical” creationComplete=”init()”>
<mx:Script>
<![CDATA[
public function onAdd():void
{
x2.structure.appendChild(<entry label=”dynamic”/>);
}
]]>
</mx:Script>
<mx:XML id=”x1″ xmlns=””>
<project label=”root”>
<metadata label=”metadata root”>
<entry label=”1st metadata entry”/>
<entry label=”2nd metadata entry”/>
</metadata>
<structure label=”content”>
<entry label=”one”>
<entry label=”one.one”/>
</entry>
<entry label=”two”/>
</structure>
</project>
</mx:XML>
<mx:XML id=”x2″ xmlns=””>
<project label=”root”>
<metadata label=”metadata root”>
<entry label=”1st metadata entry”/>
<entry label=”2nd metadata entry”/>
</metadata>
<structure label=”structure”>
</structure>
</project>
</mx:XML>

<mx:Tree id=”t1″ dataProvider=”{x1.structure}” showRoot=”false” labelField=”@label” width=”100″ height=”100″/>
<mx:Tree id=”t2″ dataProvider=”{x2.structure}” showRoot=”false” labelField=”@label” width=”100″ height=”100″/>
<mx:Button label=”Add” click=”onAdd()”/>

</mx:Application>

Second Tree Should Be Empty

Second Tree Should Be Empty

After Adding An Entry To An Empty Container The Tree Renders From The DataProviders Parent

After Adding An Entry To An Empty Container The Tree Renders From The DataProviders Parent

The first thing you notice when you run this is that while the second tree (on the left) should be empty it is in fact not! The showRoot=”false” setting does not appear to be honored if the root element doesn’t have any children. This appears to be written up at Adobe as Bug SDK-15083.

The second extremly strange behavior occurs when we add an item to the structure container that’s mapped to the second tree (we do this by clicking the Add button). Instead of ending up with a tree with our new entry, we end up with a tree that has a node for the metadata element and a node for the structure element… It appears that the databinding has been pushed up a level somehow (see picture on right.)

We were able to workaround the first bug using the workaround described in the SDK-15083 writeup. We had to force a full refresh of the data binding for the tree when adding a first item in order to resolve the second issue.