E4X фильтрация в Spidermonkey - PullRequest
2 голосов
/ 12 июня 2011

Я использую E4X в SpiderMonkey, и большинство языков кажется довольно солидным, но я не могу заставить работать фильтрацию:

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

В частности, я использую JSFL во Flash, который использует движок SpiderMonkey.

Из моих базовых знаний о E4X это довольно неожиданно / глючит, верно?Как я могу заставить эти выражения нормально работать в ActionScript / FlashPlayer!

Спасибо, Дейв

Ответы [ 2 ]

2 голосов
/ 12 июня 2011

ОК, так что я попробовал кучу вещей, и я все еще не могу заставить работать оригинальный синтаксис, поэтому лучшее, что я могу придумать (это довольно хороший обходной путь, учитывая), - это расширение прототипа 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>

Если кто-то может исправить меня, я был бы очень рад, если нет, я просто хотел бы знать, почему моя оригинальная фильтрация просто не сработала.

Дейв

0 голосов
/ 05 февраля 2018

Просто небольшая поправка к опубликованному ответу здесь относительно функции 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;
}

Оригинальное решение - лучшее, и это было именно то, что я искал!

...