在Flex中确定XML属性是否存在的最佳方法

9
我从HTTPService调用中获得了一个e4x结果格式的XML响应。

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

我尝试过:

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

但这似乎不起作用(它总是认为错误属性存在),有什么更好的方法吗?谢谢。 编辑:我也尝试将属性与null和空字符串进行比较,但没有成功...

请查看我的答案,我相信这就是你一直在寻找的! :) - Rihards
8个回答

11

你已经找到了最佳的方法:

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

attribute 方法是检索属性的首选方法,如果您不确定它们是否存在。


我认为强调这一点很重要,即这与event.result.Error.length() > 0不等同,如果Error不存在,则会失败。有关更多信息,请参见:http://www.adobe.com/livedocs/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000125.html - sixtyfootersdude
我认为你的意思是 "event.result.@Error",因为 "event.result.Error" 会查找名为 "Error" 的节点而不是属性。 - 1.21 gigawatts

5
我喜欢这种方法,因为它 a.) 非常简单易懂,b.) Ely Greenfield 也在使用它。;)
if("@property" in node){//do something}

这是一个很好的提示,不过我想再进一步,如果属性存在的话,给它分配一些值。我该怎么做?我的属性名称在一个字符串变量中,我尝试了node.@{attrNameString},但它没有起作用。有什么想法吗? - Vatsala
XML(node).attribute(attrNameString)[0] = "some value"; - 1.21 gigawatts

3
您可以通过以下方式进行检查:
if (undefined == event.result.@Error)

或者动态地
if (undefined == event.result.@[attributeName])

请注意,在您的示例中,两个点将检索所有级别上的所有后代,因此您将获得一个列表作为结果。如果没有错误属性,您将获得一个空列表。这就是为什么它永远不会等于null的原因。

2
假设在你的例子中,event.result 是一个 XML 对象,其内容与你发布的内容完全相同,那么这应该可以工作(因为验证标签是 XML 的根标签):
var error:String = event.result.@Error;
if (error != "")
    // error
else
    // no error

上面的例子假设已存在一个空值Error属性应该被视为“无错误”的情况,但如果你想知道属性是否实际上存在,你应该这样做:
if (event.result.hasOwnProperty("@Error"))
    // error
else
    // no error

2

我喜欢使用以下语法进行检查,因为它易于阅读,输入较少,并且几乎与最快的方法相当:

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

如果您不知道属性名称,但需要将值分配回该属性,请使用attribute方法:

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";
}

以下是测试属性是否存在的方法,这些方法来自于此问题的答案。由于有很多种方法,我在11.7.0.225调试播放器中对每种方法进行了测试。右侧的值是使用的方法,左侧的值是运行代码一百万次时所需的最少时间(以毫秒为单位)。以下是结果:

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

性能测试代码:

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

我已经找到了一个解决方案,但如果有更好的方法来解决这个问题,我仍然很感兴趣...

下面的代码可以解决问题:


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


0

也许你可以试试这种方式

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

0

给你:

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

很简单,是吧?:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接