@IvanMiroshin

Как найти элемент DOM с учетом вложенности по значению атрибута на php?

Есть шаблон вида:

<section name="myname1">
     ...
     <div name="myname2">
          ... 
          <p name="myname3">
               ...
          </p>
          ...
     </div>
     ...
</section>
<div name="myname4">
     ...
     <div name="myname5">
          ... 
     </div>
     ...
</div>


Задача в том чтобы найти все элементы DOM у которых есть атрибут «name» верхнего уровня со всеми вложенными в него элементами. При этом атрибут может содержать текст на кириллице, собственно так же как и вложенные конструкции в него.

Библиотеки я использовать не могу (есть требование заказчика исключить зависимости).

Первый подход к снаряду был такой:
/<\s*([a-z0-9]*)\b[^>]*\bname\s*=\s*\"([^\"]*)[^>]*>(?>(?:[^<]|<(?!\s*\/?\1\s*\b))|(<\s*\1[^>]*>(?>(?:[^<]|<(?!\s*\/?\s*\1\s*\b))|(?3))+?<\s*\/\s*\1\s*>))*<\/\1>/is

Это работает до тех пор, пока вложенность тега « ... » не вырастает более чем в 700 строк. После чего регулярное выражение просто ничего не находит. Но тут есть момент, например, если поставить вместо тега «section» тег «div», все будет работать.

Другие изыскания:
Пробовал реализацию через PHPDocument, но там возникли проблемы с кодировкой (штука в том, что я не знаю в какой кодировке будет использован разрабатываемый скрипт).

Пробовал, сначала найти « .*», а потом через функцию «preg_match_all» с флагом «PREG_OFFSET_CAPTURE» найти количество открывающихся и закрывающихся одноименных тегов и их позиции в строке, с последующим вычислением конечного закрывающего тега для искомого. Но и тут я споткнулся об пресловутую кириллицу.

Пробовал XPath, не могу добиться чтобы он корректно переваривал не до конца валидную верстку. Особенно сильно ругается на использование svg инлайном. В завершении бросает критическую ошибку:
Uncaught exception 'Exception' with message 'String could not be parsed as XML' in ...:748 Stack trace: #0 ... (748): SimpleXMLElement->__construct('
  • Вопрос задан
  • 817 просмотров
Решения вопроса 1
@IvanMiroshin Автор вопроса
Проблема решена:

/<table\b[^\>]*\bname=(\"|')?table01\1[^\>]*>(?>([^\<]+|<(?!\/?table\b))|(<table[^\>]*>(?:(?2)|(?3)|)+?<\/table>))*<\/table>/ix


Название тега: table, можно заменить на ([a-z0-9]+), тогда будет выполнен поиск по всем тагам. Главное потом подставить эту группу в соответствующие позиции в регулярном выражении.

Название и значение атрибута («name», «table01»), можно подставлять динамически (в моем случае задаются переменными php)

Все описанные мной проблемы с парсингом вложенности большого объема — решены.

Надеюсь, кому-нибудь окажусь полезным :)
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
rim89
@rim89
программист-велосипедист
Если можно искать на клиенте ( + jquery), то можно по такому селектору:
$('body > *[name]')
Если надо разгребать на php , вот есть какой то парсер - PHP Simple HTML DOM Parser и по аналогии селектором выше
Ответ написан
Комментировать
gromdron
@gromdron
Работаю с Bitrix24
Как насчет xpath ? Не смотрели в его сторону?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы