Как я могу использовать XPath и DOM для замены узла / элемента в php? - PullRequest
8 голосов
/ 06 января 2011

Скажите, у меня есть следующий HTML

$html = '
<div class="website">
    <div>
        <div id="old_div">
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <div class="a class">
                <p>some text</p>
                <p>some text</p>
            </div>
        </div>
        <div id="another_div"></div>
    </div>
</div>
';

И я хочу заменить #old_div на следующее:

$replacement = '<div id="new_div">this is new</div>';

Чтобы получить конечный результат:

$html = '
<div class="website">
        <div>
            <div id="new_div">this is new</div>
            <div id="another_div"></div>
        </div>
    </div>
';

Существует ли простая функция вырезания и вставки для этого с PHP?


Окончательный рабочий код благодаря помощи Гордона:

<?php

$html = <<< HTML
<div class="website">
    <div>
        <div id="old_div">
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <p>some text</p>
            <div class="a class">
                <p>some text</p>
                <p>some text</p>
            </div>
        </div>
        <div id="another_div"></div>
    </div>
</div>
HTML;

$dom = new DOMDocument;
$dom->loadXml($html); // use loadHTML if it's invalid XHTML

//create replacement
$replacement  = $dom->createDocumentFragment();
$replacement  ->appendXML('<div id="new_div">this is new</div>');

//make replacement
$xp = new DOMXPath($dom);
$oldNode = $xp->query('//div[@id="old_div"]')->item(0);
$oldNode->parentNode->replaceChild($replacement  , $oldNode);
//save html output
$new_html = $dom->saveXml($dom->documentElement);

echo $new_html;

?>

Ответы [ 2 ]

11 голосов
/ 06 января 2011

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

$dom = new DOMDocument;
$dom->loadXml($html); // use loadHTML if its invalid (X)HTML

// create the new element
$newNode = $dom->createElement('div', 'this is new');
$newNode->setAttribute('id', 'new_div');

// fetch and replace the old element
$oldNode = $dom->getElementById('old_div');
$oldNode->parentNode->replaceChild($newNode, $oldNode);

// print xml
echo $dom->saveXml($dom->documentElement);

Технически вам не нужен XPath для этого.Однако может случиться так, что ваша версия libxml не сможет выполнить getElementById для неподтвержденных документов (атрибуты id являются специальными в XML ).В этом случае замените вызов на getElementById на

$xp = new DOMXPath($dom);
$oldNode = $xp->query('//div[@id="old_div"]')->item(0);

Демонстрация на кодовой панели


Чтобы создать $newNode с дочерними узлами, не имеяЧтобы создавать и добавлять элементы один за другим, вы можете сделать

$newNode = $dom->createDocumentFragment();
$newNode->appendXML('
<div id="new_div">
    <p>some other text</p>
    <p>some other text</p>
    <p>some other text</p>
    <p>some other text</p>
</div>
');
0 голосов
/ 06 января 2011

сначала используйте jquery hide (), чтобы скрыть определенный div, а затем используйте append, чтобы добавить новый div

$('#div-id').remove();
$('$div-id').append(' <div id="new_div">this is new</div>');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...