Предупреждение 'xmlParseEntityRef: no name' при загрузке xml в файл php


89

Я читаю xml на php, используя simplexml_load_file. Однако при попытке загрузить xml он отображает список предупреждений

Warning: simplexml_load_file() [function.simplexml-load-file]: <project orderno="6" campaign_name="International Relief & Development" project in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

Warning: simplexml_load_file() [function.simplexml-load-file]: ional Relief & Development" project_id="313" client_name="International Relief & in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

Как исправить, чтобы удалить эти предупреждения?

(XML создается из URL-адреса http://..../index.php/site/projectsи загружается в переменную в test.php. У меня нет прав на запись в index.php)


XML недействителен. Возможно, вы вообще не сможете его загрузить. Ошибки можно подавить, добавив @перед ним simplexml_load_fileили добавив флаг, см. simplexml_load_fileДополнительную информацию на странице руководства или удалите свой вопрос, это дубликат.
hakre

Я вижу, что мой ответ привлекает довольно много внимания, если это действительно решение: не могли бы вы пометить его как «правильный ответ»? Спасибо.
ricricucit

Ответы:


143

Скорее всего, XML неверен.

Проблема могла быть в "&"

$text=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $text);

избавится от символа «&» и заменит его версией кода HTML ... попробуйте.


2
Спасибо. Ты спас мне день!
Саим

2
Лучшая практика при работе с XML - убедиться, что нет конфликтующих символов, и вам следует заменить их перед синтаксическим анализом
Mr Megamind

2
спасибо, основной смысл этого вопроса в том, что xml недействителен
Юссан 01

Небольшое дополнение, если вы хотите заменить все амперсанды, добавьте 'g' в свое регулярное выражение. Обновленное решение будет выглядеть так: $text=preg_replace('/&(?!#?[a-z0-9]+;)/g', '&amp;', $text);
flaming.codes

81

Нашел здесь ...

Проблема: синтаксический анализатор XML возвращает ошибку «xmlParseEntityRef: noname»

Причина: где-то в тексте XML есть случайный '&' (символ амперсанда), например. немного текста и еще немного текста

Решение:

  • Решение 1. Удалите амперсанд.
  • Решение 2. Закодируйте амперсанд (то есть замените &символ на &amp;). Не забудьте декодировать при чтении текста XML.
  • Решение 3. Используйте разделы CDATA (текст внутри раздела CDATA будет игнорироваться анализатором.) Например. <! [CDATA [текст и еще текст]]>

Примечание: '&' '<' '>' все вызовут проблемы, если с ними неправильно обращаться.


9
Это спасло меня сегодня.
Bwire

Знаем ли мы, почему это так? Кроме того, будет ли раздел CDATA отображаться браузером, который будет отображать некоторые из этих данных? У меня есть несколько HTML-тегов внутри моих XML-тегов, и мне нужно, чтобы они были отображены для конечного пользователя для инструмента редактирования.
sulimmesh

11

Попробуйте сначала очистить HTML с помощью этой функции:

$html = htmlspecialchars($html);

Специальные символы обычно представлены в HTML по-разному, и это может сбивать с толку компилятор. Вроде &становится &amp;.


Может кто-нибудь объяснить, почему это отклонено? htmlspecialchars()- это точная функция для преобразования &, ", <, >символов в данных элемента.
JacobRossDev

7
Этот ответ отвергнут, потому что в данном случае он не работает. Использование этой функции полностью нарушит ваш XML, преобразовав «<» в «& lt;». Я не знаю, как можно использовать htmlspecialchars()XML и не нарушать его. Я попробовал несколько флагов, но мой XML все равно сломался.
Алекс Финнарн

1
Вы должны использовать htmlspecialcharsсодержимое тега xml, а не весь XML
gbalduzzi

7

Использую комбинированный вариант:

strip_tags(preg_replace("/&(?!#?[a-z0-9]+;)/", "&amp;",$textorhtml))

1
Этот работает отлично. Вам просто не хватает конечной правой скобки
myh34d

7

ПРОБЛЕМА

  • Функция PHP simplexml_load_fileвыдает ошибку синтаксического анализа parser error : xmlParseEntityRefпри попытке загрузить файл XML с URL-адреса.

ПРИЧИНА

  • XML, возвращаемый URL-адресом, не является допустимым XML. Он содержит &значение вместо &amp;. Вполне возможно, что есть и другие ошибки, которые на данный момент не очевидны.

Вещи вне нашего контроля

  • В идеале мы должны убедиться, что в simplexml_load_fileфункцию PHP подается действительный XML , но похоже, что у нас нет никакого контроля над тем, как создается XML.
  • Также невозможно принудительно simplexml_load_fileобработать недопустимый файл XML. Это не оставляет нам множества вариантов, кроме исправления самого файла XML.

ВОЗМОЖНОЕ РЕШЕНИЕ

Преобразовать недопустимый XML в действительный XML. Это можно сделать с помощью PHP tidy extension. Дальнейшие инструкции можно найти на http://php.net/manual/en/book.tidy.php

Убедившись, что расширение существует или установлено, сделайте следующее.

/**
 * As per the question asked, the URL is loaded into a variable first, 
 * which we can assume to be $xml
 */
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<project orderno="6" campaign_name="International Relief & Development for under developed nations">
    <invalid-data>Some other data containing & in it</invalid-data>
    <unclosed-tag>
</project>
XML;

/**
 * Whenever we use tidy it is best to pass some configuration options 
 * similar to $tidyConfig. In this particular case we are making sure that
 * tidy understands that our input and output is XML.
 */
$tidyConfig = array (
    'indent' => true,
    'input-xml' => true, 
    'output-xml' => true,
    'wrap' => 200
);

/**
 * Now we can use tidy to parse the string and then repair it.
 */
$tidy = new tidy;
$tidy->parseString($xml, $tidyConfig, 'utf8');
$tidy->cleanRepair();

/**
 * If we try to output the repaired XML string by echoing $tidy it should look like. 

 <?xml version="1.0" encoding="utf-8"?>
 <project orderno="6" campaign_name="International Relief &amp; Development for under developed nations">
      <invalid-data>Some other data containing &amp; in it</invalid-data>
      <unclosed-tag></unclosed-tag>
 </project> 

 * As you can see that & is now fixed in campaign_name attribute 
 * and also with-in invalid-data element. You can also see that the   
 * <unclosed-tag> which didn't had a close tag, has been fixed too.
 */
echo $tidy;

/**
 * Now when we try to use simplexml_load_string to load the clean XML. When we
 * try to print_r it should look something like below.

 SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [orderno] => 6
            [campaign_name] => International Relief & Development for under developed nations
        )

    [invalid-data] => Some other data containing & in it
    [unclosed-tag] => SimpleXMLElement Object
        (
        )

)

 */
 $simpleXmlElement = simplexml_load_string($tidy);
 print_r($simpleXmlElement);

ВНИМАНИЕ

Разработчик должен попытаться сравнить недействительный XML с действительным XML (сгенерированным tidy), чтобы убедиться в отсутствии побочных эффектов после использования tidy. Tidy очень хорошо справляется с этим, но никогда не помешает увидеть это визуально и быть на 100% уверенным. В нашем случае это должно быть так же просто, как сравнение $ xml с $ tidy.


6

XML недействителен.

<![CDATA[ 
{INVALID XML}
]]> 

CDATA должен быть обернут вокруг всех специальных символов XML, согласно W3C.


3

На самом деле это происходит из-за того, что персонажи возятся с данными. Использование htmlentities($yourText)сработало для меня (у меня был код HTML внутри документа xml). См. Http://uk3.php.net/htmlentities .


1

Это решает мою проблему:

$description = strip_tags($value['Description']);
$description=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $description);
$description= preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $description);
$description=str_replace(' & ', ' &amp; ', html_entity_decode((htmlspecialchars_decode($description))));

1

Если у вас возникла эта проблема с opencart, попробуйте отредактировать

catalog / controller / extension / feed / google_sitemap.php Для получения дополнительной информации и того, как это сделать, обратитесь к этому: xmlparseentityref-no-name-error

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.