xml2array xmlreader

  • Автор темы Автор темы NOX
  • Дата начала Дата начала

NOX

Новичок
xml2array xmlreader

Собственно говоря требуется помошь в реализации xml2array с помощью xmlreader.

Функция возвращающая данные в зависимости от нода (т.е. текстовый, тэг или что то иное) готова. Требуется только подсказать алгоритм обхода и запихивания полученого вышесказаной функцией в соответствующие array.

Не совсем понятно, как реализовать перемещение в глубь дерева (использовать depth).
Буду благодарен за примерную (словесную) реализацию алгоритма.
 
Не совсем понятно, как реализовать перемещение в глубь дерева
ни как xmlreader, т.к. это не DOM ориентированный, он читает XML сущности последовательно.

алгоритм следующий:
- читаем XML сущность,
- проверяем ее тип

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

думаю, что данный алгоритм уже давно где-нибудь лежит на phpclassess.org
 
Большое спасибо Alexandre.Вы конечно правы нужное мне решение есть на phpclassess.org, но реализовано оно не совсем красиво (там нотисы гасятся с помощью @) и это _почти_ то что мне надо.
Чтобы поправить надо понимать как это работает.
 
но реализовано оно не совсем красиво (там нотисы гасятся с помощью @) и это _почти_ то что мне надо
я не раз использовал разные решения с phpclasses.org, и всякий раз мне их приходилось править... :(
 
Либо я что-то не понимаю, либо одно из двух :). Неполучается построить array дерево.
Загвоздка с указателем...

Если кто-нибудь поможет реализовать буду премного благодарен.
 
Эммм...Вы готового решения ждёте?
Выкладывайте проблеммные кусочки своего кода, задавайте вопросы....
 
Собственно там кода "кот наплакал".
PHP:
function parse() {
 $current = &$array;
 $xml = new XMLReader();
 $xml->XML($contents);
  while($xml->read()){
   if($xml->nodeType == XMLReader::ELEMENT){
   $parent []= &$current[$xml->localName];
   }elseif($xml->nodeType == XMLReader::END_ELEMENT){
     $last=sizeof($parent)-1;
     $current = &$parent[$last];
     unset($parent[$last]);
   }
 }
 return $array;
}

Вроде работает, но всёравно фигачит варнингию Пока функция не учитывает возможность существования нодов с одинаковыми именами на одном уровне.
проблема в том, что все ноды в дереве должны выглядеть следцющим образом
array('nodeName' => array('myText'));
т.е. как если бы все тэги были с атрибутами. В этом месте я туплю.
 
$current=&$parent[];
----
Все ноды в дереве должны выглядеть следующим образом:
PHP:
array(0 => array('name'=>'blabla', 'attributes'=>Array()),1 =>...);
А потом рекурсивно ищем нужные вам элементы.

-~{}~ 14.12.07 20:41:

ЗЫ. XMLReader - это что ? В каком виде распространяется эта либа ? Я решал эту задачу обычным xm_parser
 
Имхо: отображение xml в массив - это тупиковая ветвь развития. Потому что чтобы сделать такое отображение полным, потребуется массив огого какой - проще сразу DOM (или структуру в виде SimpleXML) использовать. Потому что необходимые фичи периодически будут добавляться. То научиться работать с ns, то сохранять порядок нод, чтобы при пересборке массива обратно в XML у нас ничего не терялось, то еще что-нибудь.
 
Wicked
При всём уважении....
Почему тупиковая ветвь ? Я не совсем понял. Что мне делать, если имеется ХМЛ файл с данными, а эти данные мне нужно получить?
По мне так...Я написал себе библиотеку с кучкой указателей, с ссылкой на родителя и проч.Написал класс оперирующий этим массивом по принципу ДОМ. И всё меня устраивает 8)
Что в этом плохого ? Конечно, такой подход не подойдёт для гигобайтного ХМЛа, но для веба ведь огромный ХМЛ и не нужен.....
 
Почему тупиковая ветвь ? Я не совсем понял. Что мне делать, если имеется ХМЛ файл с данными, а эти данные мне нужно получить?
предложено было - simpleXML
xmlWriter используется для разбора XML большого размера, так как DOM имеет особенность быть квадратично зависимым по памяти от размерности (xmlWriter почти линейно).
 
Мне не требуется полное отображение xml в массив (для этого есть удобный SimpleXML).
Хотелось бы реализовать это:
PHP:
array($nodeName => array('myText'));
где
$nodeName - название тэга,
'myText' - моя инфа (не из xml)

XMLReader - парсер на libxml. SimpleXML мне не доступен на сервере.
 
На сколько я понимаю в памяни у simpleXML только структура XML , а данные обьект берёт по мере надобности.

-~{}~ 16.12.07 05:02:

В общем если кому будет интерестно, воть:
PHP:
Class XML2Array{
	private $xml;
	function XML2Array(){$this->xml = new XMLReader();}

	function parse($contents) {
		$this->xml->XML($contents);
		$this->xml->next();
		$current = &$array[$this->xml->localName];
		$stack[0]= &$current;
		while($this->xml->read()){
		  if($this->xml->nodeType == XMLReader::ELEMENT){
		  $current = &$stack [$this->xml->depth-1];
		  $stack [$this->xml->depth]= &$current[$this->xml->localName];
		  $current = &$stack[sizeof($stack)-1];
		 }
		}
		return $array;
	}
}
Само собой сыро и надо дорабатывать, но как уже говорилось ранее мне и не нужно _полного_ xml2array (для этого лучше использовать SimpleXML).
 
В ней что всё дерево не в памяти лежит?
simpleXML основано на libxml, как и любой ДОМ. в нем лежит все дерево, даже два, однов ввиде domxml, реализованное в libxml, второе ввиде наборов hashtable, с помощью которых реализуется пхпешный объект. Хоть и осуществляется освобождение ДОМ объекта по окончанию его построения и данная память немедленно освободится, но все равно занимает повышенный расход памяти.
 
NOX
Можно задать небольшой оффтопный вопрос? Вы принципиально не испльзуете функции без классов?

Class XML2Array
К сожалению, здесь и не пахнет ООП. Создайте обычную функцию, классы здесь ни к чему.
 
Автор оригинала: Xeon303
NOX
Можно задать небольшой оффтопный вопрос? Вы принципиально не испльзуете функции без классов?

Class XML2Array
К сожалению, здесь и не пахнет ООП. Создайте обычную функцию, классы здесь ни к чему.
Принципиальный ответ :) :
Это лишь часть класса (причём сгрупированная в один метод). Остальные методы этого класса в данной теме оффтоп, впрочем также как и ваше замечание.
Хотя спасибо за внимание и потраченное время.
 
Сверху