Ваш парсер XML не врет.Это недействительный (даже не правильно сформированный) документ, который вы не сможете загрузить ни с чем.
rsquo
- это предопределенная сущность в HTML, но не в XML.В документе XML, если вы хотите использовать что-либо, кроме самых основных встроенных объектов (amp
, lt
, gt
, quot
и apos
), вы должны определить их в DTD, на который ссылается <!DOCTYPE>
декларация.(Вот как это делает XHTML.)
Вам необходимо выяснить, откуда поступил ввод, и исправить все, что было ответственным за его создание, потому что на данный момент это просто не XML.Используйте символьную ссылку (’
) или просто обычный буквенный символ ’
в кодировке UTF-8.
В качестве крайней меры, если вам действительно нужно принять эту некорректную бессмыслицу для ввода, вы можете сделать неприятную строкузамены по файлу:
$xml= file_get_contents($_FILES['file']['tmp_name']);
$xml= str_replace('’', '’', $xml);
$dom->loadXML(xml);
Если вам нужно сделать это для всех не-XML-сущностей HTML, а не только для rsquo
, это немного сложнее.Вы могли бы сделать замену регулярного выражения:
function only_html_entity_decode($match) {
if (in_array($match[1], array('amp', 'lt', 'gt', 'quot', 'apos')))
return $match[0];
else
return html_entity_decode($match[0], ENT_COMPAT, 'UTF-8');
}
$xml= preg_replace_callback('/&(\w+);/', 'only_html_entity_decode', $xml);
Это все еще не очень хорошо, поскольку он будет отображать любые последовательности символов &\w+;
внутри мест, таких как комментарии, разделы CDATA и PI, где это не так.на самом деле означает ссылку на сущность.Но, вероятно, это лучшее из того, что вы можете сделать, учитывая этот некорректный ввод.
Это, безусловно, лучше, чем вызывать html_entity_decode
по всему документу, что также испортит любые ссылки на сущности XML, что приведет к разрыву документа, когда естьсуществующий &
или <
.
Еще одним хаком, сомнительным по-разному, будет загрузка документа с использованием loadHTML()
.