DomDocument и специальные символы - PullRequest
19 голосов
/ 04 июля 2011

Это мой код:

$oDom = new DOMDocument();
$oDom->loadHTML("èàéìòù");
echo $oDom->saveHTML();

Это вывод:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>&Atilde;&uml;&Atilde;&nbsp;&Atilde;&copy;&Atilde;&not;&Atilde;&sup2;&Atilde;&sup1;</p></body></html>

Я хочу этот вывод:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>èàéìòù</p></body></html>

Я пробовал с ...

$oDom = new DomDocument('4.0', 'UTF-8');

или с 1.0 и другими вещами, но ничего.

Другое дело ... Есть способ получить такой же нетронутый HTML? Например, используя этот HTML-код во входных данных <p>hello!</p>, получите тот же вывод <p>hello!</p>, используя DOMDocument только для синтаксического анализа DOM и выполнения некоторых подстановок внутри тегов.

Ответы [ 5 ]

41 голосов
/ 08 июля 2011

Решение:

$oDom = new DOMDocument();
$oDom->encoding = 'utf-8';
$oDom->loadHTML( utf8_decode( $sString ) ); // important!

$sHtml = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
$sHtml .= $oDom->saveHTML( $oDom->documentElement ); // important!

Метод saveHTML() работает по-другому, указывая узел. Вы можете использовать основной узел ($oDom->documentElement), добавив желаемый !DOCTYPE вручную. Еще одна важная вещь - utf8_decode(). Все атрибуты и другие методы класса DOMDocument, в моем случае, не дают желаемого результата.

6 голосов
/ 04 июля 2011

Попробуйте установить тип кодировки после , когда вы загрузили HTML.

$dom = new DOMDocument();
$dom->loadHTML($data);
$dom->encoding = 'utf-8';
echo $dom->saveHTML();

Другой способ

5 голосов
/ 06 июля 2011

Проблема, по-видимому, известна, согласно комментариям пользователей на странице справки на php.net .Предлагаемые решения включают в себя вставку

<meta http-equiv="content-type" content="text/html; charset=utf-8">

в документ перед тем, как вставлять строки с символами, отличными от ASCII.

В другом хаке предлагается ввести

<?xml encoding="UTF-8">

в качествесначала текст в документе, а затем удаляя его в конце.

Противные вещи.Пахнет для меня как жук.

2 голосов
/ 31 октября 2018

Таким образом:

/**
 * @param string $text
 * @return DOMDocument
 */
private function buildDocument($text)
{
    $dom = new DOMDocument();

    libxml_use_internal_errors(true);
    $dom->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $text);
    libxml_use_internal_errors(false);

    return $dom;
}
0 голосов
/ 04 июля 2011

Похоже, вам просто нужно установить substituteEntities при создании объекта DOMDocument.

...