Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Перемещение элемента внутри XML
Форумы портала PHP.SU » » XML и его обработка » Перемещение элемента внутри XML

Страниц (1): [1]
 

1. myshara - 21 Мая, 2015 - 08:54:36 - перейти к сообщению
Привет Всем!

Кто знает каким путем можно поднять или опустить элемент внутри XML.

XML:
CODE (htmlphp):
скопировать код в буфер обмена
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <structure>
  3.     <group id='gp1'><propertis>....<propertis></group>
  4.     <group id='gp2'><propertis>....<propertis></group>
  5.     <group id='gp3'><propertis>....<propertis></group>
  6.     ...
  7.     <group id='gp32'><propertis>....<propertis></group>
  8. </structure>


Допустим, что хотим group['gp2'] расположить первым, после group['gp3'] или последним.

Как это можно реализовать?
Что нужно перемещать - знаем. Куда - тоже знаем. А как?

Неужели нужно парсить в другой файл? Или есть более красивое решение?
2. Ch_chov - 21 Мая, 2015 - 09:48:02 - перейти к сообщению
Загружаете XML в DOM объект, делаете необходимые манипуляции, сохраняете обартно в файл.
3. myshara - 21 Мая, 2015 - 15:38:41 - перейти к сообщению
Насколько я понял.
Сначала загоняем элемент в переменную.
Потом удаляем из xml.
Затем вставляем в нужное положение из переменной.

CODE (htmlphp):
скопировать код в буфер обмена
  1.     $doc = new DOMDocument('1.0', 'UTF-8');
  2.     $doc->load('xml/'.$fname);
  3.     $el = $doc->getElementById($idnode);
  4.     $el->parentNode->removeChild($el);


Но у меня на этапе:
CODE (htmlphp):
скопировать код в буфер обмена
  1. $el->parentNode->removeChild($el);


Ошибка:
CODE (htmlphp):
скопировать код в буфер обмена
  1. <b>Notice</b>:  Trying to get property of non-object in ...
  2. <b>Fatal error</b>:  Call to a member function removeChild() on a non-object in...


Что не так???
4. DeepVarvar - 21 Мая, 2015 - 16:20:01 - перейти к сообщению
Так ты проверь, нашло оно тебе элемент или нет. Судя по ошибке -- не нашло.
5. myshara - 21 Мая, 2015 - 16:42:44 - перейти к сообщению
Я понимаю что не нашел элемент.

Вопрос почему?

файл есть.
idnode - передается...

а результата нет... Почему...

Как проверить что в $doc?

Более того:
CODE (htmlphp):
скопировать код в буфер обмена
  1.     $doc = new DOMDocument('1.0', 'UTF-8');
  2.     $doc->load('xml/'.$fname);
  3.     $el = $doc->getElementsByTagName('group');
  4.    $idnode = $el->item(2)->getAttribute('id');


Строка кода:
$idnode = $el->item(2)->getAttribute('id');

Возвращает правильное значение для $idnode - gp3

Вопрос почему в таком случае не работает
CODE (htmlphp):
скопировать код в буфер обмена
  1. $doc->getElementById('gp3');
6. myshara - 21 Мая, 2015 - 19:04:02 - перейти к сообщению
Еще раз перечитал мануал

И, на сколько я понял, получается обязательное наличие у xml DTD.
Т.е. getElementById не работает без указания структуры DTD.

Тогда законный вопрос зачем оно надо???
Если мне придется формировать по тегу список, а потом воять цикл для проверки?

Т.к. в моем случае код


Дает ошибку:
CODE (htmlphp):
скопировать код в буфер обмена
  1. <b>Warning</b>:  DOMDocument::validate(): no DTD found! in ...
7. myshara - 22 Мая, 2015 - 11:02:21 - перейти к сообщению
Продолжаем.

Итак создал в xml DTD:
CODE (htmlphp):
скопировать код в буфер обмена
  1. <!DOCTYPE structure [
  2. <!ELEMENT structure (group)+>
  3. <!ELEMENT group (propertis)>
  4. <!ELEMENT propertis (name , sort , show , count? , desc?)>
  5. <!ELEMENT name (#PCDATA)>
  6. <!ELEMENT sort (#PCDATA)>
  7. <!ELEMENT show (#PCDATA)>
  8. <!ELEMENT count (#PCDATA)>
  9. <!ELEMENT desc (#PCDATA)>
  10. <!ATTLIST group id ID #REQUIRED>
  11. ]>


Теперь в php:
CODE (htmlphp):
скопировать код в буфер обмена
  1.         $el = $doc->getElementById($idnode);
  2.         $el->parentNode->appendChild($el);
  3.         $doc->save('xml/'.$fname);


Получается переместить только в конец...
А как переместить в начало???
В указанную позицию????
8. DeepVarvar - 22 Мая, 2015 - 14:22:22 - перейти к сообщению
http://php.net/manual/en/domnode...insertbefore.php
9. myshara - 22 Мая, 2015 - 14:45:14 - перейти к сообщению
DeepVarvar пишет:
http://php.net/manual/en/domnode.insertbefore.php


Спасибо.

Уже дошел и досюда...

Но прикол в том что в insertbefore надо знать позицию элемента - item($pos)

В таком случае все равно придется организовывать цикл, и получать item.
Т.к. $el = $doc->getElementById($idnode) - не имеет свойства item.

И если для установки элемента последним код такой:
CODE (htmlphp):
скопировать код в буфер обмена
  1. $el->parentNode->insertBefore($el);


А для установки первым код:

CODE (htmlphp):
скопировать код в буфер обмена
  1.             $firstel=$doc->getElementsByTagName('group')->item(0);
  2.             $el->parentNode->insertBefore($el, $firstel);


То как получить предыдущий или следующий елемент?
Без организации цикла, ведь текущий у нас уже есть???
10. DeepVarvar - 22 Мая, 2015 - 14:47:11 - перейти к сообщению
http://php.net/manual/en/class.d....previoussibling
http://php.net/manual/en/class.d...rops.nextsibling
11. myshara - 22 Мая, 2015 - 15:15:02 - перейти к сообщению
DeepVarvar пишет:
http://php.net/manual/en/class.d....previoussibling
http://php.net/manual/en/class.domnode.php#domnode.props.nextsibling


Спасибо.

Код для Up:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  $el->parentNode->insertBefore($el, $el->previousSibling);


Код для Down:
CODE (htmlphp):
скопировать код в буфер обмена
  1. $el->parentNode->insertBefore($el, $el->nextSibling->nextSibling);


Но...
При последовательном выполнении Up элемент XML меняет позицию как бы по кругу.
Т.е. если он становиться первым, то при следующем Up - он последний.

А вот при последовательном Down когда элемент уже последний возникает ошибка:
CODE (htmlphp):
скопировать код в буфер обмена
  1. <b>Notice</b>:  Trying to get property of non-object in ...


Что посоветуете?
12. DeepVarvar - 22 Мая, 2015 - 16:39:06 - перейти к сообщению
Проверять, вернулся ли в сиблингсе объект или там нулл.

 

Powered by ExBB FM 1.0 RC1