2013-10-15 2 views
0

Есть ли способ сделать это? Я хотел бы заменить один элемент другим, но каким-то образом это невозможно в PHP. Есть следующий код ($ содержание является действительным html5 в моем реальном коде, но снял некоторые вещи, чтобы сделать код короче.):Манипулировать HTML dom в PHP

$content='<!DOCTYPE html> 
<content></content> 
</html>'; 

$with='<img class="fullsize" src="/slide-01.jpg" />'; 
function replaceCustom($content,$with) { 
    @$document = DOMDocument::loadHTML($content); 
    $source = $document->getElementsByTagName("content")->item(0); 
    if(!$source){ 
    return $content; 
    } 
    $fragment = $document->createDocumentFragment(); 
    $document->validate(); 
    $fragment->appendXML($with); 
    $source->parentNode->replaceChild($fragment, $source); 

    $document->formatOutput = TRUE; 


    $content = $document->saveHTML(); 
    return $content; 
} 
echo replaceCustom($content,$with); 

Если я заменить <img class="fullsize" src="/slide-01.jpg" /> с <img class="fullsize" src="/slide-01.jpg"> то тег содержимое заменяется пустая строка. Несмотря на то, что img без закрывающего тега является абсолютно допустимым html, он не будет работать, потому что PHP, похоже, поддерживает xml. Весь пример кода, который я видел, использует appendXML для создания documentFragment из строки, но нет эквивалента HTML.

Есть ли способ сделать это, чтобы он не провалился с допустимым HTML, но недействительным XML?

+0

Не замените замену строки или регулярное выражение? – Jonathon

+0

Ваш код, похоже, работает на меня. Я не уверен, в чем проблема. –

+0

Какую версию PHP вы используете? – Spudley

ответ

2

DOMDocumentFragment::appendXML indead требует XML в моей версии (5.4.20, libxml2 Version 2.8.0). У вас есть в основном два варианта:.

  1. Предоставить действительный XML для функции (так закрывающиеся тэгом как <img />
  2. Go «длинный путь», как это было предложено в руководстве:

Если вы хотите придерживаться стандартов, вам придется создать временный DOMDocument с фиктивным корнем, а затем петлей через дочерние узлы корня ваших данных XML, добавляемые их.

$tempDoc = new DOMDocument(); 
$tempDoc->loadHTML('<html><body>'.$with.'</body></html>'); 
$body = $tempDoc->getElementsByTagName('body')->item(0); 
foreach($body->childNodes as $node){ 
    $newNode = $document->importNode($node, true); 
    $source->parentNode->insertBefore($newNode,$source); 
} 
$source->parentNode->removeChild($source); 
+0

Благодарим за ответ, работаем в этом примере, но до сих пор не загружаем контент из сообщений Wordpress, это пользовательские сообщения, содержащие вложенные html, как оболочка меню и пункты меню. Или ползунок и ползунок. Текущий код добавит каждого ребенка тела тела, но не детей этих детей, поэтому я получаю 3 пустых div для элементов слайдера. – HMR

+0

О, извините, я пропустил ', true' в' importNode() '(в этом случае он делает копию _deep_), а затем он работает. – Wrikken

+0

Теперь я вижу это только в документах. Сначала нужно было выяснить, где мой html. Просто отправил комментарий, чтобы указать, что нужно предоставить глубокую информацию, но вы уже сделали этот комментарий. Благодарим вас за помощь, я буду использовать DOMDocument, чтобы попробовать и получить вложенный контент. – HMR

Смежные вопросы