Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Обновить один XML по другому (http://www.flasher.ru/forum/showthread.php?t=194698)

mikhailk 20.02.2013 17:48

Обновить один XML по другому
 
Подозреваю, задачка пустяковая, но нет времени глубоко зарываться в документацию.

Есть два объекта XML (profile и update):

Код:

<profile>
  <user>Ivan</user>
  <userID>123123123123</userID>
  <level>2</level>
  <balance>1000</balance>
</profile>

<update>
  <level>3</level>
  <balance>1400</balance>
</update>

Нужно обновить profile по update таким образом, чтобы:

- все узлы в profile, присутствующие в update, обновились значениями из update
- все узлы в profile, отсутствующие в update, остались в прежнем виде

Т.е., итогом операции является объект XML вида


Код:

<profile>
  <user>Ivan</user>
  <userID>123123123123</userID>
  <level>3</level>
  <balance>1400</balance>
</profile>


Как проще сделать?

yasha005 20.02.2013 17:55

если это с сервака прилетает (хотя думаю тут других вариантов и нет), тогда проще сразу с сервака засылать второе один раз чем два раза первое

mikhailk 20.02.2013 17:59

Объект profile живет в клиенте и там порядка трех десятков параметров.
С сервера прилетает update и в нем как правило по три-пять параметров, которые требуют обновления, а остальные не трогаются.
Как раз хочу уйти от перекидывания лишних параметров.

yasha005 20.02.2013 18:06

Цитата:

Сообщение от mikhailk (Сообщение 1121497)
Объект profile живет в клиенте и там порядка трех десятков параметров.
С сервера прилетает update и в нем как правило по три-пять параметров, которые требуют обновления, а остальные не трогаются.
Как раз хочу уйти от перекидывания лишних параметров.

тогда закидывайте оба листинга в объект типа xml, а затем создайте метод в котором будут заменяться одни значения (в одном объекте xml) на другие (из другого объекта xml)

mikhailk 20.02.2013 18:17

Так вопрос в методе и заключался. ))

Вот такое решение получилось

Код AS3:

                private function refreshXML(basicXML:XML, update:XML) : XML
                {
                        for (var i:int = 0; i < basicXML.children().length(); i++)
                        {
                                var basicNode:XML = XML(basicXML.children()[i]);
                                for (var j:int = 0; j < update.children().length(); j++)
                                {
                                        var updateNode:XML = XML(update.children()[j]);
                                        if (basicNode.name() == updateNode.name())
                                        {
                                                basicXML.replace(basicNode.childIndex(),updateNode);
                                        }
                                }
                        }
                        return basicXML;
                }

Решение рабочее, но может проще есть вариант?

yasha005 20.02.2013 18:32

Условный оператор, который сравнивает имена xml-объектов тут явно лишний, т.к. возвращаемые объекты имён у них в любом случае будут разные, значит это условие никогда не выполнится, как следствие данные никогда не обновятся

Добавлено через 4 минуты
хотя нет, извините, всё правильно, я просто не обратил внимание на переменные, которые вы объявляете внутри цикла

Добавлено через 15 минут
Незнаю насколько это будет проще, но по некторым источникам цикл while в обратном порядке выполняется немного быстрее чем for прямом порядке, и ещё один момент: будет эффективнее если длину массива запросить единожды чем кажды раз. Хотя мне думается что это такие незначительные нюансы, которые не особо важны.

Например так:

Код AS3:

private function refreshXML(basicXML:XML, update:XML) : XML
                {
                        var i:int = basicXML.children().length();
                        var j:int;
                        var basicNode:XML;
                        var updateNode:XML;
                        while (--i > -1)
                        {
                                basicNode = XML(basicXML.children()[i]);
                                j:int = update.children().length();
                                while (--j > -1)
                                {
                                        updateNode = XML(update.children()[j]);
                                        if (basicNode.name() == updateNode.name())
                                        {
                                                basicXML.replace(basicNode.childIndex(),updateNode);
                                        }
                                }
                        }
                        return basicXML;
                }


mikhailk 20.02.2013 19:22

Да, но это все равно перебором.

yasha005 20.02.2013 19:25

Цитата:

Сообщение от mikhailk (Сообщение 1121517)
Да, но это все равно перебором.

с массивами только так и можно

alatar 20.02.2013 19:43

Зачем перебирать свойства profile? Если имена нод уникальны:

Код AS3:

for (var i:int = 0; i < update.children().length(); i++) 
{
        var updateNode:XML = XML(update.children()[i]);       
        basicXML.replace(updateNode.name(),updateNode);
}


mikhailk 20.02.2013 20:45

да, действительно работает


Часовой пояс GMT +4, время: 01:28.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.