загрузить DOMDocument с помощью специальных символов HTML (php) - PullRequest
3 голосов
/ 09 октября 2010

У меня проблема с загрузкой xml-файла с php.Я использую DOMDocument, потому что мне нужна функция getElementsByTagName.
Я использую этот код.<pre> <code>$dom = new DomDocument('1.0', 'UTF-8'); $dom->resolveExternals = false; $dom->load($_FILES["file"]["tmp_name"]); <pre> <code><?xml version="1.0" encoding="UTF-8"?> <Data> <value>1796563</value> <value>Verliebt! &rsquo;</value> </Data>

ErrorMessage:
Предупреждение: DOMDocument :: load () [domdocument.load]: объект rsquo не определен в/ tmp / php1VRb3N, строка: 4 в /www/htdocs/bla/upload.php в строке 51

Ответы [ 3 ]

2 голосов
/ 09 октября 2010

Чтобы использовать этот объект, он должен быть определен в DTD. В противном случае это неверный XML. Если у вас нет DTD, вы должны декодировать объект перед загрузкой XML с DOM:

$dom->load(
    html_entity_decode(
        file_get_contents($_FILES["file"]["tmp_name"]), 
        ENT_COMPAT, 'UTF-8'));
1 голос
/ 09 октября 2010

Ваш парсер XML не врет.Это недействительный (даже не правильно сформированный) документ, который вы не сможете загрузить ни с чем.

rsquo - это предопределенная сущность в HTML, но не в XML.В документе XML, если вы хотите использовать что-либо, кроме самых основных встроенных объектов (amp, lt, gt, quot и apos), вы должны определить их в DTD, на который ссылается <!DOCTYPE> декларация.(Вот как это делает XHTML.)

Вам необходимо выяснить, откуда поступил ввод, и исправить все, что было ответственным за его создание, потому что на данный момент это просто не XML.Используйте символьную ссылку (&#8217;) или просто обычный буквенный символ в кодировке UTF-8.

В качестве крайней меры, если вам действительно нужно принять эту некорректную бессмыслицу для ввода, вы можете сделать неприятную строкузамены по файлу:

$xml= file_get_contents($_FILES['file']['tmp_name']);
$xml= str_replace('&rsquo;', '&#8217;', $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, что приведет к разрыву документа, когда естьсуществующий &amp; или &lt;.

Еще одним хаком, сомнительным по-разному, будет загрузка документа с использованием loadHTML().

0 голосов
/ 09 октября 2010

Мое решение с помощью bobince:

    $xml= file_get_contents($_FILES['file']['tmp_name']);
    $xml= preg_replace('/&(\w+);/', '', $xml);
    $dom = new DomDocument();
    $dom->loadXML($xml);
...