【问题标题】:E4X filtering in SpidermonkeySpidermonkey 中的 E4X 过滤
【发布时间】:2011-09-13 05:00:18
【问题描述】:

我在 SpiderMonkey 中使用 E4X,大部分语言看起来都相当可靠,但我无法让过滤工作:

var xml = <root>
    <person id="dave">Dave</person>
    <person id="ian">Ian</person>
    <person>John</person>
</root>

trace( xml.*.(name() == 'person') );
trace( xml.*.(attribute('@id')) );

预期:

<person id="dave">Dave</person>
<person id="ian">Ian</person>
<person>John</person>

<person id="dave">Dave</person>
<person id="ian">Ian</person>

结果:

ReferenceError: name is not defined
ReferenceError: attribute is not defined

我什至无法让 hasOwnProperty() 工作:

xml.*.(trace( hasOwnProperty('@id') ));

false
false
false

具体来说,我在 Flash 中使用 JSFL,它使用 SpiderMonkey 引擎。

从我目前对 E4X 的基本了解来看,这是非常出乎意料/错误的,对吧?因为我可以让这些表达式在 ActionScript / FlashPlayer 中正常工作!

谢谢, 戴夫

【问题讨论】:

    标签: e4x spidermonkey jsfl


    【解决方案1】:

    好的,所以我已经尝试了很多东西,但我仍然无法让原始语法工作,所以我能提供的最好的方法(考虑到这是一个很好的解决方法)是扩展 XMLList 原型并添加一个 filter() 方法:

    XMLList.prototype.function::filter = function(callback)
    {
        var output  = new XMLList();
        var length  = input.length();
        for(var i = 0; i < length; i++)
        {
            if(callback(input[i], i, input))
            {
                output += input[i];
            }
        }
        return output;
    }
    

    所以使用以下 XML...

    var xml = <root>
        <person id="dave">Dave</person>
        <person id="ian">Ian</person>
        <person>John</person>
        <group>
            <person id="jane">Jane</person>
            <person>Sarah</person>
        </group>
    </root>
    

    抓取和过滤节点非常直观:

    // old
    var nodes = xml..person.( hasOwnProperty('@id') );
    
    // new
    var nodes = xml..person.filter( function(node){ return node.hasOwnProperty('@id'); } );
    
    <person id="dave">Dave</person>
    <person id="ian">Ian</person>
    <person id="jane">Jane</person>
    

    如果有人可以纠正我,我会非常高兴,如果没有,我只想知道为什么我的原始过滤不起作用。

    戴夫

    【讨论】:

    • 我正在寻找完全相同的解决方案。我尝试了您的示例代码,但它不起作用。我收到错误“未定义输入。
    【解决方案2】:

    对于here 发布的答案,关于filter 函数的小修正:

    XMLList.prototype.function::filter = function(callback)
    {
        var output  = new XMLList();
        var input = this;
        var length  = input.length();
        for(var i = 0; i < length; i++) {
            //console.println(i + ", " + input[i]);
            if(callback(input[i], i, input))
            {
                //console.println("Yes");
                output += input[i];
            }
        }
        //console.println('output = ' + output);
        return output;
    }
    

    原来的解决方案是最好的,这正是我想要的!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多