e4x: фильтрация по подэлементу / атрибуту с тире? - PullRequest
0 голосов
/ 01 апреля 2011

Допустим, у нас есть этот фрагмент 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?


обновление: Я получил хак для обхода проблемы в этом случае, когда я знаю, что все элементы имеют атрибут "name":

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

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

1 Ответ

2 голосов
/ 01 апреля 2011

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 (), чтобы преобразовать их в строку.

...