Ваш 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);
Если вам нужно сделать это для всех HTML сущностей не-XML а не только 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 и НЦБ, где это не на самом деле означает образование Справка. Но это, вероятно, самое лучшее, что вы можете сделать, учитывая этот сломанный вход.
Это, безусловно, лучше, чем позвонить html_entity_decode
по всему документу, что также испортит любые ссылки на сущности XML, в результате чего документ будет разбит всякий раз, когда есть существующие &
или <
.
Другим взломом, сомнительным по-разному, было бы загрузить документ, используя loadHTML()
.
Спасибо за вашу помощь. – Bendim