2011-06-11 2 views
2

Я использую E4X в SpiderMonkey, и большинство из языка кажется довольно твердым, но я не могу получить фильтрации для работы: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!

Спасибо, Dave

ответ

2

ОК, так что я перепробовал кучу вещей, и я до сих пор не могу получить оригинальный синтаксис для работы, так что лучшее, что я могу прийти с (это довольно хорошим решением , принимая во внимание) заключается в расширении XMLList прототип и добавить метод фильтра():

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> 

это довольно интуитивное, чтобы захватить и фи LTER узлы:

// 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

Я ищу точно такое же решение. Я попробовал ваш образец кода, но он не работает. I get error "вход не определен. – tarekahf

0

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

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

Смежные вопросы