Reputation: 1319
This is probably best illustrated by an example:
var xml1:XML = new XML("<root> <key>value1</key> </root>");
var xml2:XML = new XML("<root> <key>value1</key> <key>value2</key> </root>");
var xml3:XML = new XML("<root> <key>value1</key> <key2>value2</key2> </root>");
for each (var xml:XML in [ xml1, xml2, xml3 ])
{
var result:XMLList = xml.(key == "value1").key;
}
In all three cases, I expect the filtered XMLList to have one node (result.length() == 1). This is the case when operating on xml1 and xml3. However, nothing is found when filtering xml2 (result.length() == 0). The crucial difference seems to be that in xml2, the "key" child tag is repeated.
Is this a bug (compiler? runtime?) or am I doing something wrong?
Upvotes: 0
Views: 228
Reputation: 1
AS3's XML objects have some pretty cool tricks, Listing based on the tag name is super simple.
var xml:XML = new XML("<root> <key>value1</key> <key>value2</key> </root>");
var result:XMLList = xml.key;
That will create an XMLList of length 2 with every node with the tag 'key' you can also expand this for certain child nodes (i.e. xml.doors.locks.key).
You can also make lists based on a nodes attributes by using the prefix '@'.
var xml:XML = new XML("<root> <key name=\"k1\">value1</key> <key name=\"k2\">value2</key> <key name=\"k3\">value3</key> </root>");
var result:XMLList = xml.key.@name;
You can also concatenate if you have more than one list.
var xml1:XML = new XML("<root> <key>value1</key> <key>value2</key> <key>value3</key> </root>");
var xml2:XML = new XML("<root> <key>value4</key> <key>value5</key> <key>value6</key> </root>");
var list:XMLList = xml1.key;
list += xml2.key;
Hope this helps.
Upvotes: 0
Reputation: 1319
Ok, I think I've figured out how this works. I had misunderstood the syntax.
In my original example, xml.(key == "value1") selects a root node where the "key" property matches the string "value1".
In the case of xml1 and xml3, where there's only one "key" node, the value of xml.key is a single-element XMLList which string-casts to its text value, so the comparison with "value1" works.
In the case of xml2, where there are two "key" nodes, the value of xml.(key == "value1") is a two-element XMLList which string-casts two the full XML-encoded contents of the XML nodes, tags and all. So the comparison with "value1" fails and the value of the expression is empty.
No compiler or runtime bug, just a confused programmer.
Upvotes: 0
Reputation: 2331
Actually, I would have expected it to return an XMLList
of length 2 in the case of xml2
. It should select parent elements which contains a node named "key" with the value "value1", then filter all the nodes named "key".
Not sure why it doesn't, though. This is some E4X syntax that would do what I describe above:
var result:XMLList = xml.(descendants("key").text().contains("value1")).key;
result
lengths:
On the other hand, if what you're expecting is only the nodes named "key" and with the value "value1", you can try this:
var result:XMLList = xml..key.(text() == "value1");
result
lengths:
Upvotes: 1