e4x: фильтрация по подэлементу/атрибуту с тире?

Допустим, у нас есть этот фрагмент e4x:

zoo = <zoo />;
zoo.animal += <animal animal-type='bear' name='Woofer' />;
zoo.animal += <animal animal-type='panda' name='Ling-Ling' />;
zoo.animal += <animal animal-type='seal' name='Arthur' />;

Я могу фильтровать имена, начинающиеся с W или L:

js>zoo.animal.(@name.match(/^[WL]/))
<animal animal-type="bear" name="Woofer"/>
<animal animal-type="panda" name="Ling-Ling"/>

Но как фильтровать по типам животных? В атрибуте "animal-type" есть тире, поэтому я не могу использовать синтаксис @animal-type, а более общий синтаксис ['@animal-type'] не работает как селектор предиката.

Есть ли способ выбрать текущий узел в предикате фильтрации e4x?


обновление: у меня есть обходной путь в этом случае, когда я знаю, что все элементы имеют атрибут «имя»:

js>zoo.animal.(@name.parent()['@animal-type'].match(/^[bp]/))
<animal animal-type="bear" name="Woofer"/>
<animal animal-type="panda" name="Ling-Ling"/>

Но это не сработает в целом.


обновление 2: Ой! Так близко:

f1=function(attr) { 
  var b = attr.match(/bear/) != null; 
  writeln(attr+":"+b); 
  return b;
}
f2=function(attr) { 
  var b = attr.match(/bear/) != null; 
  writeln(attr+":"+b); 
  return true;
}

js>zoo.*.(f1(@['animal-type']))
bear:true
panda:false
seal:false
js>zoo.*.(f2(@['animal-type']))
bear:true
panda:false
seal:false
<animal animal-type="bear" name="Woofer"/>
<animal animal-type="panda" name="Ling-Ling"/>
<animal animal-type="seal" name="Arthur"/>

ВТФ? Я могу получить доступ к атрибуту animal-type, и если я верну безусловную истину, я могу использовать функцию в качестве предиката фильтра, но если я верну результат сравнения, он, похоже, проигнорирует этот результат.


person Jason S    schedule 01.04.2011    source источник


Ответы (1)


Argh -- интерпретатор Javascript был в каком-то странном состоянии, когда я работал. Вот что работает, если я начну с нуля:

zoo = <zoo />;
zoo.animal += <animal animal-type='bear' name='Woofer' />;
zoo.animal += <animal animal-type='panda' name='Ling-Ling' />;
zoo.animal += <animal animal-type='seal' name='Arthur' />;

js>zoo.animal.(@['animal-type'].match(/^[bp]/))
<animal animal-type="bear" name="Woofer"/>
<animal animal-type="panda" name="Ling-Ling"/>
js>zoo.animal.(@['animal-type'].match(/^[ps]/))
<animal animal-type="panda" name="Ling-Ling"/>
<animal animal-type="seal" name="Arthur"/>

Я также должен быть осторожен, если он возвращает один результат:

js>zoo.animal.(@['animal-type'].match(/^p/))
js>zoo.animal.(@['animal-type'].match(/^p/)).toXMLString()
<animal animal-type="panda" name="Ling-Ling"/>

Узлы XML выглядят «невидимыми», если у них нет дочерних элементов или текстового содержимого + вам нужно вызвать toXMLString(), чтобы преобразовать их в строку.

person Jason S    schedule 01.04.2011
comment
Спасибо. Нашел это очень полезным. - person MonkeyWrench; 06.12.2012