Верх страницы
Обложка к записи DOMDocument
Время для прочтения: 0 мин. 59 сек.

DOMDocument

DOMDocument — класс для работы с XML-документами. Данный инструмент удобно использовать, когда вам необходимо парсить xml/html-документы.

Простой пример использования класса DOMDocument:

$dom = new DOMDocument();
$dom->loadHTML( $html );
$dom->saveHTML();

Рассмотрим основные ошибки и сложности с которыми можно столкнуться:

  • Кодировка
  • Невалидный документ
  • Выбор елементов
  • Удаление елементов

Кодировка

Для начала документ нужно загрузить с корректной кодировкой. В случае, если мы работаем не со всей страницей, а например с каким-то блоком, то элементов <head> и <body> нет и, соответственно, тега для указания кодировка тоже нет. DOMDocument доставит теги <head> и <body> самостоятельно, но кодировку нам нужно будет указать самостоятельно:

$dom->loadHTML( '<meta charset="utf-8">' . $html );
// или
$dom->loadHTML( '<?xml encoding="utf-8" ?>' . $html );

Так же документ необходимо правильно сохранить:

$dom->saveHTML( $dom->documentElement );

Иногда нам нужно на выходе получить конкретный елемент, а не весь документ, то мы так же можем это сделать:

$dom->saveHTML( $dom->getElementById( 'element' ) );

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

$html = '';
$body_items = $dom->getElementsByTagName( 'body' )->item( 0 )->childNodes;
foreach ( $body_items as $node ) {
	$html .= $dom->saveHTML( $node );
}

Иногда приходится работать с невалидными документами. При загрузке DOMDocument исправит разметку. Можно убрать warnings с помощью следующей конструкции:

libxml_use_internal_errors( true );
$dom->loadHTML( $html );
libxml_clear_errors();

Выборки

Простые выборки можно сделать с помощью методов DOMDocument:

public getElementById ( string $elementId ) : DOMElement
public getElementsByTagName ( string $name ) : DOMNodeList
public getElementsByTagNameNS ( string $namespaceURI , string $localName ) : DOMNodeList

Любые выборки можно сделать с помощью объекта класса DOMXPath, который реализовывает спецификацию XPath:

СелекторДействие
/h1Выбрать все теги h1 в корне документа
body/h1Выбрать все теги h1 которые внутри body
body//h1Выбрать все теги h1 которые внутри body не зависимо от вложенности
//h1Выбрать все теги h1
//h1[@title]Выбрать все теги h1 с атрибутом title
//h1[@title=»Name title»]Выбрать все теги h1 с атрибутом title=»Name title»
//h1[span]Выбрать все теги h1 с тегом span внутри
//h1[span=»Some text»]Выбрать все теги h1 с тегом <span>Some text</span> внутри
//h1[span>40]Выбрать все теги h1 с тегом span у которого nodeValue > 40
*Выбрать все элементы
//@*Выбрать все атрибуты
//h1/*Выбрать все дочерние элементы тега h1
//title[@*]Выбрать все элементы с атрибутов title
//h1 | //h2Выбрать все элементы h1 и h2

XPath — не так прост, чем привычные всем CSS-селекторы, но XPath мощнее и может включать в себя функции, операторы сравнении, поиск элемента с дочерним элементом и другое.

Примеры функций XPath:

  • contains()
  • text()
  • starts-with()
  • sum()
  • count()
//a[starts-with( @href, ‘#’ )]Выбрать все теги a, у которых ссылка начинается с символа «#»

Проблема удаления

Если мы хотим удалить узел, то весь документ перестраивается. Следующий код отработает правильно только при первом удалении.

foreach( $elements as $element ) {
    $element->parentNode->removeChild($href);
}

Решением является перебор елементов начиная с конца массива:

for ( $i = $elements->length; --$i >= 0; ) {
    $element = $elements->item($i);
    $element->parentNode->removeChild($href);
}

Источник: WP Punk.

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, Opencart, DLE, Laravel, Moonshine, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Предыдущая запись
Следующая запись

Давайте дружить
в Телеграме

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы