Сохранить разрывы строк внутри тегов <p>, используя DOMXPath? - PullRequest
4 голосов
/ 19 января 2011

В настоящее время я использую PHP и DOMXPath для получения содержимого всех элементов <p> веб-страницы:

<?php
...    
$doc = new DOMDocument();
$doc->loadHTML($html);

$xpath = new DOMXPath($doc);
$paragraphs = $xpath->evaluate("/html/body//p");

foreach ($paragraphs as $paragraph){
echo $paragraph->textContent . "<br />";
}

Моя проблема в том, что строка, полученная из textContent, не учитывает теги <br />, которые существуют в этих элементах <p>. Вместо этого он удаляет разрыв строки и объединяет слова, которые обычно находятся в отдельных строках. Например:

Пример HTML:

<p>
Some happy talk goes here talking about our great product.<br />
We would love for you to buy it!
</p>

<p>
Random information and what not<br />
Isn't that cool?
</p>

Текущий вывод из PHP выше:

Some happy talk about our great product.We would love for you to buy it!

Random information and what notIsn't that cool?

Я тоже попробовал $paragraphs = $doc->getElementsByTagName("p");, и это дает мне то же самое.

Есть ли способ заставить DOMXPath / DOMDocument сохранить разрывы строк? Мне нужно иметь возможность отделить каждое слово в абзаце, и текущий вывод запрещает это.

Если есть альтернативный метод для извлечения строки из элементов <p> с сохранением <br /> или '\n', это также было бы здорово.

EDIT


После дальнейшего изучения рассматриваемый HTML на самом деле представляет собой список якорей, разделенных тегами <br>, но без разрывов строк:

<p class="home_page_list"><a href="/home/personal-banking/checking/Category-Page-Classic-Checking/classic-checking.html">Classic Checking</a><br> <a href="/home/personal-banking/checking/Category-Page-Interest-Checking/interest-checking.html">Interest Checking</a><br> <a href="/home/personal-banking/checking/Category-Page-Interest-Checking/interest-premium-checking.html">Premium Checking</a><br> <a href="/home/personal-banking/Savings-Category-Page/Basic-Savings-Category-Page/basic-savings.html">Savings Plans</a><br> <a href="/home/personal-banking/Savings-Category-Page/Money-Market-Accounts-Category-Page/money-market-accounts.html">Money Market Accounts</a><br> <a href="/home/personal-banking/Savings-Category-Page/Certificates-of-Deposit-Category-Page/fixed-rate-CD.html">CDs</a><br> <a href="/home/personal-banking/Savings-Category-Page/Individual-Retirement-Account-Category-Page/individual-retirement-account.html">IRAs</a></p>

Оказывается, это правильно работает с исходным HTML-кодом.

ОБНОВЛЕНИЕ: решено


С помощью ответа @ ircmaxell и комментариев, оставленных @netcoder и @Gordon, это было решено, это не очень элегантно, но пока подойдет.

* * Пример тысячу сорок четыре: * * 1045
foreach ($paragraphs as $paragraph){
    $p_text = new DOMDocument();
    $p_text->loadHTML(str_ireplace(array("<br>", "<br />"), "\r\n", DOMinnerHTML($paragraph)));
    //Do whatever, in this case get all of the words in an array.
    $words = explode(" ", str_ireplace(array(",", ".", "&", ":", "-", "\r\n"), " ", $p_text->textContent));
print_r($words);
}

При этом используется DOMinnerHTML (в соответствии с предложением @netcoder) для замены экземпляров <br> на "\ r \ n" (в соответствии с предложением @ircmaxell), которые затем можно оценить после textContent.

Очевидно, что есть место для улучшений, но это решило мою текущую проблему.

Спасибо за помощь всем,

Ben

Ответы [ 3 ]

4 голосов
/ 19 января 2011

Хорошо, я бы заменил разрывы строк на буквальные разрывы строк:

$doc = new DOMDocument();
$doc->loadHTML($html);

$brs = $doc->getElementsByTagName('br');
foreach ($brs as $node) {
    $node->parentNode->replaceChild($doc->createTextNode("\r\n"), $node);
}


$xpath = new DOMXPath($doc);
$paragraphs = $xpath->evaluate("/html/body//p");

foreach ($paragraphs as $paragraph){
    echo $paragraph->textContent . "<br />";
}
2 голосов
/ 19 января 2011

Одна из возможностей

echo simplexml_import_dom($paragraph)->asXML();
1 голос
/ 25 июля 2013

У меня такая же ситуация, я использую:

$document->loadHTML(str_replace('<br>', urlencode('<br>'), $string_or_file));

И я использую urlencode (), чтобы вернуть его обратно для отображения или вставки в базу данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...