9

I have a XML response from an HTTPService call with the e4x result format.


<?xml version="1.0" encoding="utf-8"?>
<Validation Error="Invalid Username/Password Combination" />

I have tried:


private function callback(event:ResultEvent):void {
    if(event.result..@Error) {
        // error attr present
    }
    else {
        // error attr not present
    }
}

This does not seem to work (it always thinks that the error attribute exits) what is the best way to do this? thanks.

EDIT: I have also tried to compare the attribute to null and an empty string without such success...

mmattax
  • 27,172
  • 41
  • 116
  • 149

8 Answers8

11

You have found the best way to do it:

event.result.attribute("Error").length() > 0

The attribute method is the preferred way to retrieve attributes if you don't know if they are there or not.

Theo
  • 131,503
  • 21
  • 160
  • 205
  • I think that it is important to emphasis that this is NOT equivalent to `event.result.Error.length() > 0` which will fail if Error does not exist. For more info see: http://www.adobe.com/livedocs/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000125.html – sixtyfootersdude Feb 18 '11 at 22:21
  • I think you meant, "event.result.@Error" since event.result.Error would look for the node named "Error" instead of the attribute. – 1.21 gigawatts Jun 13 '13 at 11:20
5

I like this method because a.) it's painfully simple and b.) Ely Greenfield uses it. ;)

if("@property" in node){//do something}
Paul Mignard
  • 5,824
  • 6
  • 44
  • 60
  • This is a great tip, however I would like to go one step further and assign some value to the attribute if it exists. How do I do it? My attribute name is in a string variable, and I tried node.@{attrNameString} and it dint work. any ideas? – Vatsala Jul 02 '10 at 04:59
  • `XML(node).attribute(attrNameString)[0] = "some value";` – 1.21 gigawatts Jul 19 '15 at 18:41
3

You can check this in the following way:

if (undefined == event.result.@Error)

or dynamically

if (undefined == event.result.@[attributeName])

Note that in your example, the two dots will retrieve all descendants on all levels so you'll get a list as a result. If there are no Error attributes, you'll get an empty list. That's why it will never equal null.

Christophe Herreman
  • 15,895
  • 9
  • 58
  • 86
2

Assuming that in your example event.result is an XML object the contents of which are exactly as you posted, this should work (due to the fact that the Validation tag is the root tag of the XML):

var error:String = event.result.@Error;
if (error != "")
    // error
else
    // no error

The above example will assume that an existing Error attribute with an empty value should be treated as a "no-error" case, though, so if you want to know if the attribute actually exists or not, you should do this:

if (event.result.hasOwnProperty("@Error"))
    // error
else
    // no error
hasseg
  • 6,787
  • 37
  • 41
2

I like to use the following syntax to check because it's easy to read, less typing and it nearly tied as the fastest method:

if ("@style" in item) // do something

To assign a value back to that attribute when you don't know the name of it before hand use the attribute method:

var attributeName:String = "style";
var attributeWithAtSign:String = "@" + attributeName;
var item:XML = <item style="value"/>;
var itemNoAttribute:XML = <item />;

if (attributeWithAtSign in itemNoAttribute) {
    trace("should not be here if attribute is not on the xml");
}
else {
    trace(attributeName + " not found in " + itemNoAttribute);
}

if (attributeWithAtSign in item) {
    item.attribute(attributeName)[0] = "a new value";
}

All of the following are ways to test if an attribute exists gathered from the answers listed on this question. Since there were so many I ran each in the 11.7.0.225 debug player. The value on the right is the method used. The value on the left is the lowest time in milliseconds it takes when running the code one million times. Here are the results:

807    item.hasOwnProperty("@style")
824    "@style" in item
1756   item.@style[0]
2166   (undefined != item.@["style"])
2431   (undefined != item["@style"])
3050   XML(item).attribute("style").length()>0

Performance Test code:

var item:XML = <item value="value"/>;
var attExists:Boolean;
var million:int = 1000000;
var time:int = getTimer();

for (var j:int;j<million;j++) {
    attExists = XML(item).attribute("style").length()>0;
    attExists = XML(item).attribute("value").length()>0;
}

var test1:int = getTimer() - time; // 3242 3050 3759 3075

time = getTimer();

for (var j:int=0;j<million;j++) {
    attExists = "@style" in item;
    attExists = "@value" in item;
}

var test2:int = getTimer() - time; // 1089 852 991 824

time = getTimer();

for (var j:int=0;j<million;j++) {
    attExists = (undefined != item.@["style"]);
    attExists = (undefined != item.@["value"]);
}

var test3:int = getTimer() - time; // 2371 2413 2790 2166

time = getTimer();

for (var j:int=0;j<million;j++) {
    attExists = (undefined != item["@style"]);
    attExists = (undefined != item["@value"]);
}

var test3_1:int = getTimer() - time; // 2662 3287 2941 2431

time = getTimer();

for (var j:int=0;j<million;j++) {
    attExists = item.hasOwnProperty("@style");
    attExists = item.hasOwnProperty("@value");
}

var test4:int = getTimer() - time; // 900 946 960 807

time = getTimer();

for (var j:int=0;j<million;j++) {
    attExists = item.@style[0];
    attExists = item.@value[0];
}

var test5:int = getTimer() - time; // 1838 1756 1756 1775
1.21 gigawatts
  • 16,517
  • 32
  • 123
  • 231
1

I have figured out a solution, I'm still interested if there is a better way to do this...

This will work:


private function callback(event:ResultEvent):void {
    if(event.result.attribute("Error").length()) {
        // error attr present
    }
    else {
        // error attr not present
    }
}

mmattax
  • 27,172
  • 41
  • 116
  • 149
0

Here you go:

if(event.result.@error[0]){
    //exists 
}

Easy, eh? :)

Rihards
  • 10,241
  • 14
  • 58
  • 78
0

May be you can try this way

if (undefined == event.result.@[attributeName]);
Srikrushna
  • 4,366
  • 2
  • 39
  • 46
lojolis
  • 1
  • 2