XML HTTPService Result и для каждого

XML - это круто в гибкости, но мне нужно решить неприятную проблему, вызванную тем, что я могу представить, это особенность. Видите ли, когда у вас есть только один тег чего-то, он создает объект, который не является массивом. Но когда находит более одного, он помещает их в структуру массива.

Я хочу решить это элегантно. Любая рекомендация.

Пример: это иллюстрирует результат HTTP-запроса:

private function initXMLRes(event:ResultEvent):void
{
    var resObj:Object = event.result;
    //
    for each(var i:Object in resObj.specifictag)
    {
        // to use specifictag attributes, etc. example:
        Alert.show(specifictag.name);
    }
}

Код ранее будет работать с 2+ элементами. Он примет этот xml:

<specifictag name="one" /><specifictag name="two" />

... но не этот:

<specifictag name="one" />

Я мог бы проверить формат resObj.specifictag (чтобы проверить, есть ли у него массив), а затем продублировать код (для каждого случая). Но - даже если он вызывает функцию - я не думаю, что это элегантное решение.

Что ж, надеюсь, у кого-то есть хорошее представление по этому поводу. (По опыту знаю, что у SO гораздо больше экспертов по C ++, чем по гибкости, но что ж ...)

Идеально было бы, чтобы HTTPrequest обрабатывал каждый тег согласованным образом (всегда используя массивы ... хотя я предполагаю, что это также будет иметь свои недостатки).

Спасибо!


person huff    schedule 03.03.2010    source источник


Ответы (3)


Проблема, я думаю, на самом деле является ошибкой, которую вы можете обработать в обработчике результатов HTTPService и заставить возвращенный объект превратиться в коллекцию массивов. Вот отрывок из моего приложения.

if (evt.result.rows.row is ArrayCollection) {
    MyAC= evt.result.rows.row;
}else{
    MyAC= new ArrayCollection(ArrayUtil.toArray(evt.result.rows.row));
}

У вас должно получиться так:

var resObj:Object = new Object();

if (event.result.rows.row is ArrayCollection) {
    resObj= event.result
}else{
    resObj= new ArrayCollection(ArrayUtil.toArray(event.result));
}
person invertedSpear    schedule 03.03.2010
comment
Что ж, у меня получилось аналогичное решение, но мне гораздо больше нравится ваш фрагмент кода. : D - person huff; 03.03.2010

Это мое текущее решение:

// historial
var hist:ArrayCollection = new ArrayCollection();
if(resObj.hist[0])
  hist = resObj.hist;
else
  hist.addItem(resObj.hist);
person huff    schedule 03.03.2010

Похоже, ваши <specifictag> элементы находятся на верхнем уровне, а не внутри какого-то другого корня? XML-документ может иметь только один корень, поэтому в этом случае вы фактически получаете XML-документ в некоторых случаях и ArrayCollection XML-документов в других случаях. Если вы измените службу, чтобы она всегда возвращала один XML-контейнер, который имеет specifictag в качестве дочерних элементов, вам не придется беспокоиться об этой проблеме.

Следующий код демонстрирует, что итерация по одному элементу работает так же, как итерация по нескольким при работе с объектами XML.

private function init():void {
    trace("Iterating two children");
    iterate(<root><child /><child /></root>);
    trace("Iterating one child:");
    iterate(<root><child /></root>);
}

private function iterate(x:XML):void {

    for each(var element:XML in x.child) {
        trace(element.name());
    }
}
person Samuel Neff    schedule 03.03.2010
comment
Нет, они находятся в корне XML ... Я попытаюсь поместить в корневой тег, чтобы посмотреть, считаются ли они там ArrayCollection. Спасибо! - person huff; 03.03.2010
comment
Это тоже не работает, где бы они ни стояли. - person huff; 03.03.2010