E4X & XMLList fails when defined in a switch statement.

This one had me REALLY confused, for a good bit of time, luckily a co-worker helped be go through a rather vigorous debugging session to pinpoint the problem. Apparently if you are attempting to access a piece of a larger XML object using the new E4X capabilities and you attempt to do it with a single line of code, it will return a null object instead of the expected XMLList object it should. After looking into it further, I discovered that if you define the variable, but don’t set it’s value on the same line, then it works fine… See wonky huh?

Example (Based on Adobes example documentation):

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package
{
import flash.display.Sprite;
 
public class XMLListExample extends Sprite
{
	private var books:XML;
 
	public function XMLListExample()
	{
		books =		<books>
			<book publisher="Addison-Wesley" name="Design Patterns" />
			<book publisher="Addison-Wesley" name="The Pragmatic Programmer" />
			<book publisher="Addison-Wesley" name="Test Driven Development" />
			<book publisher="Addison-Wesley" name="Refactoring to Patterns" />
			<book publisher="O'Reilly Media" name="The Cathedral & the Bazaar" />
			<book publisher="O'Reilly Media" name="Unit Test Frameworks" />
		</books>;
 
		showBooksByPublisher();
	}
 
	private function showBooksByPublisher():void
	{
		var ner = "ren";
		switch(ner){
			case "ren":
			// the working code
			var results:XMLList;// = new XMLList();
			results = books.book.(@publisher == "Addison-Wesley");
			trace("results:\n"+results); // returns a the first 4 items (which contain "Adison...")
 
			// now for the fun!!!
			var otherResults:XMLList = books.book.(@publisher == "O'Reilly Media");
			trace("other results:\n"+otherResults); // returns null? (actually a null object)
 
			// just to see if oneline variable definitions work
			var test:String = 'ner';
			trace("test string: "+test);
 
			// seeing what else is a problem to do this way
			var objTest:Object = {ner:"ren"};
			trace('test object: '+objTest.ner); // yup works fine.
			//
			var xmlTest:XML = <ners>
			<ner>ren</ner>
			</ners>;
			trace('test xml:\n'+xmlTest); // no problem here either.
			//
			var numTest:Number = 45;
			trace('test number: '+numTest); // this is fine too.
			break;
		}
		if(ner == "ren")
		{
			var otherOtherResults:XMLList = books.book.(@publisher == "O'Reilly Media");
			trace("other other results:\n"+otherOtherResults); // works fine as well.
		}
	}
}// end of class
}

Download the code.

Tell your friends, I’m letting Adobe know. And please let us know if your testing shows differently.

  • http://www.zorked.com Jordan

    Yeah, I ran into this exact same problem. It will work fine inside the switch unless you do a filter predicate. I’m assuming it’s a problem with scoping that query. I find it surprising that this wasn’t caught. You’ve filed a bug report then?

  • http://bent.paperclipped.com nilloc

    Yeah i got a reply, from Adobe a couple of days ago, it looks like they discovered it around the same time I did:
    http://bugs.adobe.com/jira/browse/ASC-2901

  • http://www.atticmedia.com Joe

    Thanks!! I’ve been trying to work out what was going wrong for well over an hour… Thanks to your site and Google I have solved the problem! The whole programming team here thanks you! 🙂

  • Filip Hoeven

    Searched for hours why the code didn’t work as expected.
    Looked on the net for answers. After several days and different searches found this site.

    Can’t understand why such a bug is this old and still not fixed!

    switch (menuItemType)
    {
    case …:
    // This doesn’t work (returns null, no exception thrown)
    var result:XMLList = myXMLList.(@myAttrib == …);
    // This works.
    var result:XMLList;
    result = myXMLList.(@myAttrib == …);