Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

интелектуальный перевод xml в массив (Александр Шустов)
Author Message
Александр Шустов
Заглянувший



Joined: 18 Sep 2006
Posts: 16
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Mon Sep 18, 2006 4:45 pm (написано за 7 минут 25 секунд)
   Post subject: интелектуальный перевод xml в массив
Reply with quote

Добрый день,
Никак не могу разобраться с, казалось бы, простой вещью..
Необходимо перевести xml в массив, НО:
если елемент содержит ноды с одинаковыми названиями, то класть их в нумерованный массив, если с разными, то в ассоциативный, т.е.
Code (xml): скопировать код в буфер обмена
<values>
        <value>val1</value>
        <value>val2</value>
        <value>val3</value>
</values>
такой xml должен добавляться так:
Code (php): скопировать код в буфер обмена
$result['values'][] = $value;
а такой:
Code (xml): скопировать код в буфер обмена
<values>
        <name1>val1</value>
        <name2>val2</value>
        <name3>val3</value>
</values>
так:
Code (php): скопировать код в буфер обмена
$result['values'][$name] = $value;
Т.е. мне нужно сочинить само условие, по которому различать приведенные варианты.
Подскажите какие решения могут быть?
Пишу на php5, так что разбирать могу с помощью SimpleXML или DOM.
Back to top
View user's profile Send private message
collapse
Участник форума



Joined: 05 Sep 2006
Posts: 78
Карма: 0
   поощрить/наказать


PostPosted: Mon Sep 18, 2006 6:10 pm (спустя 1 час 25 минут; написано за 3 минуты 23 секунды)
   Post subject:
Reply with quote

Ну так ....
Code (php): скопировать код в буфер обмена
        if(isset (www.php.net/isset)($result['values']))
        {
        if(is_array (www.php.net/is_array)($result['values']){
             $result['values'][]=$value;       
        }        else {
             $buf=$result['values'];
           $result['values']=array (www.php.net/array)();
           $result['values'][]=$buf;
           $result['values'][]=$value;       
             }
        }
Back to top
View user's profile Send private message
Александр Шустов
Заглянувший



Joined: 18 Sep 2006
Posts: 16
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Tue Sep 19, 2006 4:22 am (спустя 10 часов 12 минут; написано за 4 минуты 51 секунду)
   Post subject:
Reply with quote

Идею почерпнул, спасибо.
Вот что получилось, может кому пригодится:
Code (php): скопировать код в буфер обмена
function xmlToArray($node_list, $ignore_attr = false){
                // $node_list это DOMNodeList
                $result = array (www.php.net/array)();
                for($i = 0;$i < $node_list->length;$i++){

                        $node = $node_list->item($i);
                        $node_name  = $node->nodeName;

                        // если узел текстовый, то пишем его значение и continue
                        if($node->nodeType == XML_TEXT_NODE){

                                $result = $node->nodeValue;
                                continue;
                        }

                        if($node->nodeType == XML_ELEMENT_NODE){

                                // определяем куда будем подцеплять новый элемент...
                                // если такой элемент уже существует, то надо что-то делать
                                if (isset (www.php.net/isset)($result[$node_name])) {

                                        // если элемент является строкой или массивом без нулевого
                                        // элемента, значит будем переносить эту строку или ветвь
                                        if ((!is_array (www.php.net/is_array)($result[$node_name])) || (!isset (www.php.net/isset)($result[$node_name][0]))) {

                                                $old = $result[$node_name];
                                                unset (www.php.net/unset)($result[$node_name]);
                                                $result[$node_name] = array (www.php.net/array)();
                                                $result[$node_name][] = $old;
                                        }
                                        $dest = & $result[$node_name][];

                                } else {
                                        //такого элемента нет, можно смело создать
                                        $dest = & $result[$node_name];
                                }

                                if($node->hasChildNodes()){
                                        // если есть потомки, то разбираемся с ними...
                                        $dest = $this->xmlToArray($node->childNodes, $ignore_attr);
                                } else {
                                        // ...если нет, значит это пустой элемент
                                        $dest = '';
                                }
                        }

                        // разбираемся с атрибутами
                        if (!$ignore_attr) {

                                // если они вообще есть...
                                if ($node->hasAttributes()) {

                                        $attributes = $node->attributes;
                                        $attr_array = array (www.php.net/array)();

                                        for($j = 0;$j < $attributes->length;$j++) {
                                                $attr = $attributes->item($j);
                                                $attr_array['@'.$attr->nodeName] = $attr->nodeValue;
                                        }
                                        // разбираемся куда их писать:
                                        // атрибуты у текстовых элементов ИГНОРИРУЮТСЯ!
                                        // у остальных пишутся с ключами вида: [@имя_атрибута]
                                        if (empty (www.php.net/empty)($dest)) {
                                                $dest = $attr_array;
                                        } elseif (is_array (www.php.net/is_array)($dest)) {
                                                $dest = array_merge (www.php.net/array_merge)($dest, $attr_array);
                                        }
                                }
                        }
                }
                return $result;
        }
Usage:
Code (php): скопировать код в буфер обмена
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->load($xml_file_path);
$root = $dom->documentElement;
$node_list = $root->childNodes;

xmlToArray($node_list);
Этот метод переводит xml в симпатичные массивчики с логикой описаной выше.
Любые ноды кроме XML_ELEMENT_NODE и XML_TEXT_NODE игнорируются.
Заглавную страницу этого форума в xml'е переводит в массив за ~0.04 сек
Back to top
View user's profile Send private message
LeoSR
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Feb 07, 2007 12:49 pm (спустя 4 месяца 18 дней 8 часов 26 минут; написано за 1 минуту 49 секунд)
   Post subject: XML в массив и обратно
Reply with quote

перевод XML в массив и обратно.
исходники здесь: mysrc.blogspot.com/2007/02/php-xml-to-array-and-backwards.html
как работает, смотрите примерыЖ)
шлите комменты:)

Example #1 (1.xml):
Code (xml): скопировать код в буфер обмена
<ddd>
 <onemore dd="55">
  <tt>333</tt>
  <tt ss="s1">555</tt>
  <tt>777</tt>
 </onemore>
 <two>sdf rr</two>
</ddd>
The code:
Code (php): скопировать код в буфер обмена
$xml=xml2ary(file_get_contents (www.php.net/file_get_contents)('1.xml'));
print_r (www.php.net/print_r)($xml);
Here is the Array result:

Format XML->Array
_c - children
_p - parent (строить xml можно и без него)
_v - value
_a - attributes
Code (php): скопировать код в буфер обмена
Array (www.php.net/array)
(
   [ddd] => Array (www.php.net/array) (
           [_c] => Array (www.php.net/array) (
                   [_p] => Array (www.php.net/array) *RECURSION*
                   [onemore] => Array (www.php.net/array) (
                           [_a] => Array (www.php.net/array) (
                                   [dd] => 55
                               )
                           [_c] => Array (www.php.net/array) (
                                   [_p] => Array (www.php.net/array)  *RECURSION*
                                   [tt] => Array (www.php.net/array) (
                                           [0] => Array (www.php.net/array) (
                                                   [_v] => 333
                                               )
                                           [1] => Array (www.php.net/array) (
                                                   [_a] => Array (www.php.net/array) (
                                                           [ss] => s1
                                                       )
                                                   [_v] => 555
                                               )
                                           [2] => Array (www.php.net/array) (
                                                   [_v] => 777
                                               )
                                       )
                               )
                       )
                   [two] => Array (www.php.net/array) (
                           [_v] => sdf rr
                       )
               )
       )
)
Example #2: (1.xml as described before)
Code (php): скопировать код в буфер обмена
$xml=xml2ary(file_get_contents (www.php.net/file_get_contents)('1.xml'));
$xml['ddd']['_c']['twomore']=vclone($xml['ddd']['_c']['onemore']);
$xml['ddd']['_c']['twomore']['_c']['tt'][0]['_v']='hello';
echo (www.php.net/echo) ary2xml($xml);
Will output result:
Code (xml): скопировать код в буфер обмена
<ddd>
 <onemore dd="55">
  <tt>hello</tt>
  <tt ss="s1">555</tt>
  <tt>777</tt>
 </onemore>
 <two>sdf rr</two>
 <twomore dd="55">
  <tt>hello</tt>
  <tt ss="s1">555</tt>
  <tt>777</tt>
 </twomore>
</ddd>
Back to top
amixen
Участник форума



Joined: 04 Jul 2005
Posts: 32
Карма: 0
   поощрить/наказать


PostPosted: Sun Apr 22, 2007 10:06 am (спустя 2 месяца 14 дней 21 час 17 минут; написано за 3 минуты 27 секунд)
   Post subject:
Reply with quote

Спасибо, LeoSR!
Оч. помог! Я вот только немного модернизировал...
Code (php): скопировать код в буфер обмена
if (isset (www.php.net/isset)($r['attributes'])) {
 foreach ($r['attributes'] as $k=>$v) {
  //$cv['_a'][$k]=$v;
  $cv['_a'][$k] = (is_utf8($v)) ? utf2win($v) : $v ;
 }
}
Что бы сразу переводить в кирилицу...
Вобще удобная маленькая функция, как раз для таких вещей как мне надо, например обновление модулей в моем CMS. XML-файл маленький до 10 Кбайт.
Поэтому монстров для разбора XML-кода не нужно ;-)
Back to top
View user's profile Send private message Send e-mail
Emily1991
Заглянувший



Joined: 05 Nov 2013
Posts: 1
Карма: 0
   поощрить/наказать

Location: Buffalo

PostPosted: Tue Nov 05, 2013 8:23 pm (спустя 6 лет 6 месяцев 13 дней 10 часов 17 минут; написано за 5 секунд)
   Post subject:
Reply with quote

Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML