views:

1808

answers:

2

From some xml I want to find items that have a specific attribute and value.

Here is example xml:

<node>
 <node>
  <node>
   <special NAME="thisone"></special>
  </node>
  <node>
   <special>dont want this one</special>
  </node>
 </node>
</node>

(nodes can contain nodes...)

I need to find the first based on it has an attribute named "NAME" and value of "thisone".

then I need its parent (node).

I tried this:

specialItems = tempXML.*.(hasOwnProperty("NAME"));

but didnt seem to do anything.

??

Thanks!

A: 

You could do this in 2 ways:

  1. add the NAME attribute to all your special nodes, so you can use an E4X conditions(xml)
  2. use a loop to go through special nodes and check if there is actually a NAME attribute(xml2)

Here is an example:

//xml with all special nodes having NAME attribute
var xml:XML = <node>
 <node>
      <node>
        <special NAME="thisone"></special>
      </node>
      <node>
        <special NAME="something else">dont want this one</special>
      </node>
     </node>
</node>
//xml with some special nodes having NAME attribute
var xml2:XML = <node>
 <node>
      <node>
        <special NAME="thisone"></special>
      </node>
      <node>
        <special>dont want this one</special>
      </node>
     </node>
</node>

//WITH 4XL conditional
var filteredNodes:XMLList = xml.node.node.special.(@NAME == 'thisone');
trace("E4X conditional: " + filteredNodes.toXMLString());//carefull, it traces 1 xml, not a list, because there only 1 result,otherwise should return 
//getting the parent of the matching special node(s)
for each(var filteredNode:XML in filteredNodes)
    trace('special node\'s parent is: \n|XML BEGIN|' + filteredNode.parent()+'\n|XML END|');

//WITHOUGH E4X conditional
for each(var special:XML in xml2.node.node.*){
    if([email protected]()){
        if(special.@NAME == 'thisone')  trace('for each loop: ' + special.toXMLString() + ' \n parent is: \n|XML BEGIN|\n' + special.parent()+'\n|XML END|');
    }
}

There is a pretty good and easy to follow article on E4X on the yahoo flash developer page.

George Profenza
Either of these would work, though they're not necessary. The response would make a lot more sense to me if the two approaches were presented separately (i.e., in separate code blocks).
Michael Brewer-Davis
+3  A: 

In ActionScript you'll use E4X rather than XPath, generally. What you want can be achieved like this:

var xml:XML = <node>...</node>;
var selected:XMLList = xml.descendants().(attribute("NAME") == "thisone");      
var first:XML = selected[0];
var parent:XML = first.parent();

If you know the node you want is a special, then you can use:

var selected:XMLList = xml..special.(attribute("NAME") == "thisone");

instead. Here's a nice E4X tutorial.

If you use the @NAME == "thisone" syntax, then you do need the NAME attribute on all of your XML nodes, but not if you use the attribute() operator syntax instead.


I added the parent() call above; you could get the parent directly by using the child only in the conditional:

xml..node.(child("special").attribute("NAME") == "thisone");        
Michael Brewer-Davis
nice answer! +1 :)
George Profenza
Wow, this is really great- how would I get the parent of the found items included in the result? (the nodes around the special nodes)
Scott
add a .parent() method at the end of the line that finds the item
invertedSpear
So the first example works, where you find the attribute, select the first (0) element, then find the parent.However, I like your second example, but it does not seem to work. If I have only one matching 'NAME' in the document, it throws a Coercion failed, cant conver XML to XMLList. If there is more than one, it does not throw an error, but there is no data - the XMLList is empty.??
Scott
@Scott: I'm not seeing issues using variants of the data in your original post. What does your real data look like? I don't get data if I have multiple `<special>` tags in one `<node>`--not sure why, probably the attribute("NAME") is a list that doesn't convert to "thisone".
Michael Brewer-Davis