Блочный редактор и парсер DOM, дайджест обновлений Битрикс, выпуск #3

  • Блочный редактор и парсер DOM, дайджест обновлений Битрикс, выпуск #3

    Антон Долганин 12 Февраля 2016 8:02 5100
    В этом обновлении от 8 февраля смотрим новый блочный редактор Битрикс, а также парсер DOM для разработчиков. Код из видео в самом посту.



    Подписаться на меня можно: в Facebook, Youtube, Twitter. Шлите ваши комментарии и замечания.

    Код:

    //получаем страницу для препарирования
    $http = new \Bitrix\Main\Web\HttpClient;
    $html = $http->get('http://test.d-it.ru/site_rm/');
    
    $start = microtime(true);
    
    //и начинаем работать с DOM
    $doc = new \Bitrix\Main\Web\DOM\Document;
    $doc->loadHTML($html);
    
    printf('Разложили доку за %.4F с.', microtime(true) - $start);
    $start = microtime(true);
    
    //в теории вам никто не мешает написать свой парсер, возможно, измененный от HtmlParser
    //$doc->setQueryEngine(HtmlParser);
    
    echo '<h2>Поиск querySelector</h2>';
    $selector = 'div.item-image img[width=75]';
    $resultList = $doc->querySelectorAll($selector);
    foreach($resultList as $node) {
       echo $node->getAttribute('src');
       echo ' У картинки '.($node->hasAttributes('alt') ? ' есть альт ' : ' нет альта');
       echo '<br/>';
    
       //если бы ноды получали как обширные части документа, то могли бы выполнять аналогично поиск внутри них
       //$node->querySelector();
       //$node->querySelectorAll();
    
       //довольно много методов тут http://bxapi.ru/?module_id=main&class=Node
       //не забываем, что в передаваемых параметрах некоторым методам фигурирует в основном так же нода
       //возвращаются часто тоже элементы DOM
    }
    
    printf('Прошло %.4F с.', microtime(true) - $start);
    $start = microtime(true);
    
    echo '<h2>Поиск по тегам</h2>';
    $elementList =& $doc->getElementsByTagName('meta');//А еще есть: getElementById / getElementByClassName
                                        /// getElementsByName / getElementsByClassName / getElementsByAttr
    foreach($elementList as &$element) {
       print_r(array_keys($element->getAttributesArray()));
       //заметьте, что мы намеренное работаем по ссылке с $element, чтобы управлять DOM-ом
       //для режима чтения ссылка не обязательна
       $element->setId('blabla_'.rand(1, 100));//установка id
       $element->setName('blabla_'.rand(1, 100));//установка name
       $element->setStyle('top: '.rand(1, 100).'px');//установка style
       $element->setAttribute('data-my', 'мой аттрибут');//установка любого аттрибута
       $element->getAttribute('data-my');//получение любого аттрибута
       //больше очевидных методов здесь http://bxapi.ru/?module_id=main&class=Element
       echo '<br/>';
    }
    
    printf('Прошло %.4F с.', microtime(true) - $start);
    $start = microtime(true);
    
    echo '<h2>Добавим элемент</h2>';
    $div = $doc->createElement('div');
    $div->setAttribute('data-my', 'my new div');
    $div->setInnerHTML('link: <a href="/about/">click me</a>');
    $parent = $doc->getBody();//получаем родителя нашего дива, пусть это будет body
    $parent->appendChild($div);
    
    
    printf('Прошло %.4F с.', microtime(true) - $start);
    $start = microtime(true);
    
    echo '<h2>Посмотрим, что изменилось</h2>';
    echo htmlspecialcharsbx($doc->saveHTML());
    
    printf('Прошло %.4F с.', microtime(true) - $start);
    $start = microtime(true);
    
    //еще методы
    //$doc->getHead();//вернет шапку документа как часть DOM
    //$doc->getBody();//вернет тело документа как часть DOM
    
    //поддержки пока нет, но обещает быть интересным
    //$doc->getTextContent();//тексовой содержимое документа?
    
    //на домашнее задание
    //$doc->adoptNode($node);//перемещение ноды между документами
    //new \Bitrix\Main\Web\DOM\Element\Input;//инпут выделен как отдельный элемент DOM
     

    .
Анатолий
24 Февраля 2016 19:09
Штука конечно хорошая и полезная, но вот setInnerHTML без тегов текст не записывает.
Антон Долганин
25 Февраля 2016 4:47
Анатолий, а можно пример кода вашей проблемы?
Анатолий
25 Февраля 2016 10:35
$html = '<body></body>';

$doc = new \Bitrix\Main\Web\DOM\Document;
$doc->loadHTML($html);

$div = $doc->createElement('div');
$div->setInnerHTML('click me - link');

echo $div->getInnerHTML();
Анатолий
25 Февраля 2016 10:37
$html = '<body></body>';

$doc = new \Bitrix\Main\Web\DOM\Document;
$doc->loadHTML($html);

$div = $doc->createElement('div');
$div->setInnerHTML('<a href="/about/">click me</a> - link');

echo $div->getOuterHTML();
 


.
Антон Долганин
29 Февраля 2016 14:51
Говорят, ошибка скорее всего. Поизучают еще детальнее и поправят, ежели что.
tester
13 Ноября 2017 17:44
а как удалять ненужные элементы?

$node->getParentNode()->removeChild($node);
не удаляет