Php xml удалить узел

PHP SimpleXML – удалить узел xpath

Я немного смущен относительно того, как я могу удалить родительский узел чего-то, что я могу найти через поиск по xpath:

$xml = simplexml_load_file($filename); $data = $xml->xpath('//items/info[item_id="' . $item_id . '"]'); $parent = $data[0]->xpath("parent::*"); unset($parent); 

Таким образом, он находит идентификатор элемента, никаких проблем нет, но unset не избавляется от этого узла . Все, что я хочу сделать, это удалить . для этого продукта. Очевидно, что в XML-файле есть множество узлов поэтому он не может удалить unset($xml->data->items) поскольку это удалит все.

'); unset($xml->b); echo $xml->asxml(); с '); unset($xml->b); echo $xml->asxml(); 

это работает по назначению (удаление элемента из документа), потому что вызывается метод __unset () (или эквивалент в коде модулей).
Но когда вы вызываете unset($parent); он удаляет только ссылку на объект, хранящуюся в $ parent, но не влияет на сам объект или документ, хранящийся в $ xml. Для этого я вернусь к DOMDocument .

loadxml('   123    456    789   '); $item_id = 456; $xpath = new DOMXpath($doc); foreach($xpath->query('//items[info/item_id="' . $item_id . '"]') as $node) < $node->parentNode->removeChild($node); > echo $doc->savexml(); 

Это работает для меня. Не unset($parent); но unset($parent[0]); :

$res = $xml->xpath('//key/k[. = "string"]/parent::*'); $parent = $res[0]; unset($parent[0]); 

Это работает путем создания саморекламы к элементу simplexml в $parent (или $res[0] ).

Более подробное объяснение см. В соответствующем ответе в связанном вопросе. Удалите дочерний элемент с определенным атрибутом в SimpleXML для PHP .

Один из способов – импортировать узел SimpleXML в DOMDocument, а затем удалить в DOMDocument. Не очень прямо, но он работает:

$xml = simplexml_load_file($filename); $result = $xml->xpath("/cardsets/cardgroup"); foreach ($result as $el) < if ($el['id'] == $id) < $domRef = dom_import_simplexml($el); $domRef->parentNode->removeChild($domRef); $dom = new DOMDocument('1.0'); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->loadXML($xml->asXML()); $dom->save($filename); break; > > 

Я бы наверняка подошел к этой проблеме как к фильтрующей, а не к удаленной.

Читайте также:  2 col div css

Таким образом, копирование необходимых узлов в другую строку или создание другого документа XML, если на то пошло. Вы знаете, какие инструменты вы используете для таких сценариев.

Я думаю, что это не только решает вашу проблему, но, вероятно, помогает вам легче читать и понимать. Тем не менее, вы не уверены в производительности. Расскажите, сколько узлов вы регулярно работаете.

Источник

DOMNode::removeChild

This functions removes a child from a list of children.

Parameters

Return Values

If the child could be removed the function returns the old child or false on error.

Errors/Exceptions

DOM_NO_MODIFICATION_ALLOWED_ERR

Raised if this node is readonly.

DOM_NOT_FOUND

Raised if child is not a child of this node.

Examples

The following example will delete the chapter element of our XML document.

Example #1 Removing a child

$doc = new DOMDocument ;
$doc -> load ( ‘book.xml’ );

$book = $doc -> documentElement ;

// we retrieve the chapter and remove it from the book
$chapter = $book -> getElementsByTagName ( ‘chapter’ )-> item ( 0 );
$oldchapter = $book -> removeChild ( $chapter );

The above example will output:

See Also

  • DOMChildNode::remove() — Removes the node
  • DOMNode::appendChild() — Adds new child at the end of the children
  • DOMNode::replaceChild() — Replaces a child

User Contributed Notes 14 notes

You can’t remove DOMNodes from a DOMNodeList as you’re iterating over them in a foreach loop. For example.

$domNodeList = $domDocument -> getElementsByTagname ( ‘p’ );
foreach ( $domNodeList as $domElement ) <
// . do stuff with $domElement.
$domElement -> parentNode -> removeChild ( $domElement );
>
?>

. will seemingly leave the internal iterator on the foreach out of wack and results will be quite strange. Though, making a queue of items to remove seems to work. For example.

$domNodeList = $domDocument -> getElementsByTagname ( ‘p’ );
$domElemsToRemove = array();
foreach ( $domNodeList as $domElement ) <
// . do stuff with $domElement.
$domElemsToRemove [] = $domElement ;
>
foreach( $domElemsToRemove as $domElement ) <
$domElement -> parentNode -> removeChild ( $domElement );
>
?>

This might be obvious, but might help someone as well.

If you simply have a node that you need to remove (perhaps from an xpath) and don’t know the parent node offhand (the examples seem to assume you have the parent in a variable), then you can do something easy like this.

parentNode is a scalar property of the Element.

These two functions might be helpful to anyone trying to delete a node and all of its children:

function deleteNode ( $node ) <
deleteChildren ( $node );
$parent = $node -> parentNode ;
$oldnode = $parent -> removeChild ( $node );
>

function deleteChildren ( $node ) <
while (isset( $node -> firstChild )) <
deleteChildren ( $node -> firstChild );
$node -> removeChild ( $node -> firstChild );
>
>
?>

For those who don’t understand >sbeam at onsetcorps dot net on 02-Feb-2005 12:07< 'hack', here's a little discussion:

First but *wrong* try would be:
foreach ( $parent -> childNodes as $child ) <
$parent -> removeChild ( $child );
?>
This doesn’t work because DOM tree id modified on-the-fly and this confuses foreach loop.

The idea behind sbeam’s trick is that after removing the first item in the first iteration, the second item in childNodes nodelist immediately becomes the first item. That’s why we must _always_ remove the first child. Here’s another implementation:

$count = $parent -> childNodes -> length ;
for ( $i = 0 ; $i < $count ; $i ++) <
$oldNode = $parent -> removeChild ( $parent -> childNodes -> item ( 0 )); // . not item($i) .
>
?>

Just a note, if you remove a node the whitespace it occupied will remain if you save the file.

To avoid this, use $document->preserveWhiteSpace = false;

$document = new DomDocument ();
$document -> preserveWhiteSpace = false ;
?>

Note that iterating through the childNodes array and removing those children will stop the iteration.

For example:
foreach( $node -> childNodes as $child )
<
if( iWantToDeleteThisNode ( $child ))
$child -> parentNode -> removeChild ( $child );
>
?>

Will not work. Note that in removing the node, the childNodes array gets rebuilt (it seems) and so only the first item will be removed. In order to properly remove all the children you want to remove, you will need to do something like the following:

$nodesToDelete = array();
foreach( $node -> childNodes as $child )
<
if( iWantToDeleteThisNode ( $child ))
$nodesToDelete [] = $child ;
>
foreach( $nodesToDelete as $node )
<
$node -> parentNode -> removeChild ( $node );
>
?>

I believe this is actually more efficient than the first snippet would be (if it worked) but obviously I cannot benchmark it.

You can use foreach to remove multiple elements from a DOMNodeList, only if you use a temporary array or via XPath query.
If not, the simplest way will be:

while ( $element = $nodeList -> item ( 0 )) $element -> parentNode -> removeChild ( $element );
>

This method will remove all child nodes but leave the attributes (and namespace declarations) intact.

Источник

Русские Блоги

Simplexml — это метод для PHP -обработки XML -файлов. Другой — обработка DOM. Здесь мы говорим только Simplexml.
В настоящее время PHP -обработка XML более используется, а более зрелой является DOM. Но DOM более критичен с точки зрения скорости и кода.

Некоторые функции Simplexml требует более высокой версии PHP, и рекомендуется PHP5,2 или выше.

Во -первых, новый XML

Метод 1 (обычный новый файл):

 '; $xmlContent.=''; $xmlContent.=' '; $xmlContent.=' 

Метод 2 (Используйте simplexml Недавно построенный):

$fp=fopen(111.xml','w'); $xmlContent=' '; fwrite($fp,$xmlContent); fclose($fp); $xml=simplexml_load_file('111.xml'); $app=$xml->addChild('nav'); $app->addAttribute('id',"1"); $ App-> addChild («имя», «я и я»); $app->addChild('color','#000000'); $app=$xml->addChild('nav'); $app->addAttribute('id',"2"); $ App-> addChild ('name', 'you, you, you'); $app->addChild('color','#ffffff); $app=$xml->addChild('nav'); $app->addAttribute('id',"3"); $ App-> addchild («имя», «он и он»); $app->addChild('color','#cccccc); $xml->asXML('111.xml'); 

Можно видеть, что первый метод на самом деле — просто обычные записи. Поскольку я проверил время выполнения двух методов и обнаружил, что первый метод использовался меньше времени, рекомендуется использовать обычные новые методы файлов для создания нового XML -файла!

Недавно построенная структура файла следующая:

       

Во -вторых, прочитать XML

 if($xml=simplexml_load_file('111.xml'))< foreach($xml->nav as $list) < $value[]=get_object_vars($list); >>else

Функция get_object_vars состоит в том, чтобы преобразовать объект в массив, чтобы значение $ — это обычный массив PHP. Вы можете использовать_r для взгляда на этот массив.

В -третьих, изменить XML

1 Новый узел

 $xml=simplexml_load_file('111.xml'); $app=$xml->addChild('nav'); $app->addAttribute('id',"4"); $ App-> addchild ('name', 'it it'); $app->addChild('color','#000000'); $xml->asXML('111.xml'); 

Добавить в последний узел

2 , Изменить узел

 $xml=simplexml_load_file('111.xml'); $xg=$xml->xpath("/navlist/nav[@id='3']"); $ xg [0]-> name = "Привет, он"; $xg[0]->color="#444444"; $xml->asXML('111.xml'); 

Модифицированные узлы с идентификатором атрибута NAV до 3

3 , Удалить узлы

Необходимо удалить узел с помощью функции Unset, но более трудно удалить указанный узел. Удаление указанного узла может использовать только значение индекса узла.

Например, удалите второй узел (ID 2):

$xml=simplexml_load_file('111.xml'); unset($xml->nav[1]); $xml->asXML('111.xml'); 

Индекс начинается с 0, поэтому индекс второго узла составляет 1.

Если вы хотите удалить его с помощью указанного атрибута, вам необходимо циклироваться все узлы, чтобы получить индексы узлов указанных атрибутов
следующим образом:

$xml=simplexml_load_file('111.xml'); $i=0; foreach($xml as $dup)< $sc=$dup->attributes(); if($sc['id']==2)< unset($xml->nav[$i]); > $i++; > $xml->asXML('111.xml'); 

В -четвертых, удалить XML

пятьXML Document и PHP в том же файле

     Подробности    Подробности 2    Подробности 3   XML; $movies = new SimpleXMLElement($xmldoc); foreach($movies as $key => $value) < // Получить атрибут $attr = $value->title->attributes(); echo "Id:" . $attr['id'] . "
"; echo "Title:" . $value->title . "
"; echo "Details:" . $value->details . "

"; > //$words = $lib->xpath("//word"); // echo $words[0]['add'].'
'; echo $movies->title[0]; ?>

Результаты вывода:

Id:1 Название: PHP XML -обработка Введение 1. Подробности: Подробности 1 Id:2 Название: PHP XML -обработка Введение II Подробности: Подробности 2 Id:3 Название: PHP XML -обработка Введение II Подробности: подробный контент три 

Источник

Оцените статью