Компонент DomCrawler в основном используется в приложениях Symfony для помощи в функциональных тестов для фильтрации узлов DOM документов HTML/XML. Методы, предоставляемые DomCrawler, изначально были вдохновлены jQuery, такие как eq()
, first()
, children()
, nextAll()
и т. д.
В Symfony 4.4 добавили три новых метода, часто запрашиваемых сообществом: match()
, closest()
и outerHtml()
. Рассмотрим следующий фрагмент HTML:
<html lang="en">
<body>
<div class="class-1">
<h1 class="class-1">Lorem Ipsum</h1>
<ul class="class-2 class-3" id="id-1">
<li>1</li>
<li class="class-4">2</li>
<li>3</li>
</ul>
</div>
</body>
</html>
Метод match(string $selector)
возвращает true
, если узел соответствует данному селектору CSS:
$crawler->filter('#id-1')->matches('.class-3'); // true
$crawler->filter('#id-1')->matches('.class-4'); // false
Метод closest(string $selector)
возвращает первого предка узла, который соответствует данному селектору CSS:
// returns the div.class-1 node and NOT the h1.class-1 node because h1 is
// a sibling and not an ancestor of ul#id-1
$crawler->filter('#id-1')->closest('.class-1');
Метод outerHtml()
возвращает все содержимое HTML узла, включая его собственные теги:
// returns '<ul class="class-2 class-3" id="id-1"><li>1</li><li class="class-4">2</li><li>3</li></ul>'
$crawler->filter('#id-1')->outerHtml();
// returns '<li>1</li><li class="class-4">2</li><li>3</li>'
$crawler->filter('#id-1')->html();
Удаление лишних пробелов
Работа с пробелами довольно раздражает при проверке содержимого некоторых тегов HTML. Например, со следующим фрагментом HTML:
<div class="class-1">
<h2>
Some Title Text
</h2>
</div>
Следующий тест не пройдет из-за всех «n» и пробелов, окружающих текст заголовка:
// this fails because of the extra white spaces
$this->assertSame('Some Title Text', $crawler->filter('.class-1')->text());
В Symfony 4.3 ввели метод assertSelectorTextContains()
, чтобы помочь в этих ситуациях, но начиная с Symfony 4.4, вы также можете передать true
в качестве второго необязательного аргумента text()
, чтобы удалить все лишние пробелы:
// this passes because all extra white spaces are removed
$this->assertSame('Some Title Text', $crawler->filter('.class-1')->text(null, true));
Помимо обрезки пробелов в начале и конце строки, эта функция также заменяет два или более пробелов внутри содержимого одним пробелом. Например, если исходный текст foo bar baz
, он возвращает foo bar baz
.