在Haxe.xml.Fast中使用空内容安全地解析innerData

时间:2014-11-16 12:28:18

标签: xml haxe

使用haxe.xml.Fast解析haxe中的xml时,我很难读取innerData。

我正在尝试在名为XMLUtil

的自定义类中使用这些实用程序函数
public static function getNodeNamed(parent:Fast, nodeName:String):Fast {
    if ( parent.hasNode.resolve(nodeName)) {
        return parent.node.resolve(nodeName);
    }else {
        return null;
    }
}

public static function getNodeText(parent:Fast, nodeName:String):String {
    var node : Fast = getNodeNamed(parent, nodeName);

    try {
        return node.innerData.toString(); // Still crashing here, although it's in a try-catch block
    }catch (err:Error) {
        return "";
    }
    return null;
}

当我解析一个不一定有内部数据的节点时(参见'触发'节点)

<dialog id="tut4_2" repeat="2">
        <text>Blah blah blah</text>
        <triggers></triggers>
        <triggered>tut4_1</triggered>       
    </dialog>

访问节点的innerData

时,我遇到了崩溃
var triggers:String = XMLUtil.getNodeText(newDialog, "triggers");

这是运行时错误

[Fault] exception, information=triggers does not have data
Fault, get_innerData() at Fast.hx:140

我真正无法得到的最奇怪的事情是,我在try-catch块中调用innerData,但我的功能仍在崩溃。

为什么会发生这种情况,如何以安全便捷的方式访问innerData

我正在使用Haxe 3.1.3和NME 3.0

P.S我知道Fast意味着使用更严格的XML结构,但是我正在从as3项目移植大型XML文件集合,我不想更改XML内容。我只想以编程方式处理它。

3 个答案:

答案 0 :(得分:2)

来自文档:

  

您可以使用不同类型的多个catch块来处理   不同种类的例外。动态类型将捕获所有   例外:

try {
   // ...
} catch( msg : String ) {
   trace("Error message : " + msg );
} catch( errorCode : Int ) {
   trace("Error #"+errorCode);
} catch( unknown : Dynamic ) {
   trace("Unknown exception : "+Std.string(unknown));
}

如果catch语句与错误类型不匹配,则表示错误将被捕获。这是使用Dynamic的重点。您也可以将类型留下相同的效果:

catch( unknown ) {
   trace("Unknown exception : "+Std.string(unknown));
}

答案 1 :(得分:1)

这可能已过时,但我认为有必要抛出错误:

    var fu:Float;
    var a:Float=5;
    var b:Float=0;
    try{
        fu=a/b;
        throw("error")
    }
    catch(err:String){trace("oops");}

我无法使用Error类型。 http://old.haxe.org/doc/cross/exceptions

答案 2 :(得分:0)

我不确定这是最好的解决方案,但我通过实际复制和更改haxe.xml.Fast get_innerData方法来解决这个问题,所以我让它返回null而不是抛出异常

public static function getNodeText(parent:Fast, nodeName:String):String {
    var _node : Fast = getNodeNamed(parent, nodeName);

    try{
        var it :Iterator<Xml> = _node.x.iterator();
        if ( !it.hasNext() )
            //was : throw name+" does not have data";
            return null;
        var v = it.next();
        var n = it.next();
        if( n != null ) {
            // handle <spaces>CDATA<spaces>
            if( v.nodeType == Xml.PCData && n.nodeType == Xml.CData && StringTools.trim(v.nodeValue) == "" ) {
                var n2 = it.next();
                if( n2 == null || (n2.nodeType == Xml.PCData && StringTools.trim(n2.nodeValue) == "" && it.next() == null) )
                    return n.nodeValue;
            }
            //was : throw name+" does not only have data";
            trace( _node.name + " does not only have data");
            return null;
        }
        if( v.nodeType != Xml.PCData && v.nodeType != Xml.CData )
            //was : throw name+" does not have data";
            return null;

        return v.nodeValue;

    }catch (err:Error) {
        return null;
    }
}