'xmlParseEntityRef: no name' попередження під час завантаження xml у php-файл


90

Я читаю 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

Відповіді:


145

XML, швидше за все, недійсний.

Проблемою може бути "&"

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

позбудеться знака "&" і замінить його на його версію HTML-коду ... спробуйте.


2
Дякую. Ти врятував мій день!
Саїм,

2
Найкраща практика під час роботи з XML полягає у тому, щоб переконатись, що немає суперечливих символів, і вам слід замінити їх перед парсином
містер

2
дякую, головне в цьому питанні полягає у тому, що xml недійсний
yussan

Лише невелике додавання, якщо ви хочете замінити всі амперсанди, додайте '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 все ще зламався.
Alex Finnarn,

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;. Цілком можливо, що існують інші помилки, які не є очевидними на даний момент часу.

РЕЧІ, ЩО НЕ ВИДАЮТЬСЯ

  • В ідеалі ми повинні переконатися, що дійсний XML подається у simplexml_load_fileфункцію PHP , але схоже, ми не маємо ніякого контролю над тим, як створюється 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. Тіді робить надзвичайно хорошу роботу, роблячи це правильно, але ніколи не заважає бачити це візуально і бути впевненим на 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))));

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.