Ostrzeżenia „xmlParseEntityRef: no name” podczas ładowania xml do pliku php


89

Czytam xml w php przy użyciu simplexml_load_file. Jednak podczas próby załadowania xml wyświetla listę ostrzeżeń

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

Jak poprawić, aby usunąć te ostrzeżenia?

(XML jest generowany z http://..../index.php/site/projectsadresu URL i ładowany do zmiennej w test.php. Nie mam uprawnień do zapisu do index.php)


XML jest nieprawidłowy. Możesz w ogóle nie być w stanie go załadować. Błędy można wyeliminować, dodając je @przed simplexml_load_filelub dodając flagę, zapoznaj się ze stroną podręcznika, simplexml_load_fileaby uzyskać więcej informacji i usuń pytanie, jest to duplikat.
hakre

Widzę, że moja odpowiedź cieszy się sporym zainteresowaniem, jeśli to jest rozwiązanie: czy możesz oznaczyć ją jako „prawidłową odpowiedź”? dzięki.
ricricucit

Odpowiedzi:


143

XML jest najprawdopodobniej nieprawidłowy.

Problemem może być „&”

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

usunie znak „&” i zastąpi go jego wersją kodu HTML ... spróbuj.


2
Dziękuję Ci. Uratowałeś mi dzień!
Saim

2
Najlepszą praktyką podczas pracy z XML jest upewnienie się, że nie ma sprzecznych znaków i należy je zastąpić przed parsinem
Mr Megamind

2
dzięki, głównym punktem tego pytania jest to, że xml jest nieprawidłowy
yussan

Tylko mały dodatek, jeśli chcesz zamienić wszystkie znaki &, dodaj „g” do swojego wyrażenia regularnego. Zaktualizowane rozwiązanie wyglądałoby tak: $text=preg_replace('/&(?!#?[a-z0-9]+;)/g', '&amp;', $text);
flaming.codes

81

Znalazłem to tutaj ...

Problem: parser XML zwraca błąd „xmlParseEntityRef: noname”

Przyczyna: gdzieś w tekście XML znajduje się zbłąkany „&” (znak ampersand), np. trochę tekstu i trochę więcej tekstu

Rozwiązanie:

  • Rozwiązanie 1: Usuń znak ampersand.
  • Rozwiązanie 2: Zakoduj znak ampersand (czyli zamień &znak na &amp;). Pamiętaj o dekodowaniu podczas czytania tekstu XML.
  • Rozwiązanie 3: Użyj sekcji CDATA (tekst wewnątrz sekcji CDATA zostanie zignorowany przez parser). <! [CDATA [trochę tekstu i trochę więcej tekstu]]>

Uwaga: wszystkie '&' '<' '>' spowodują problemy, jeśli nie zostaną poprawnie rozwiązane.


9
To mnie dzisiaj uratowało.
Bwire,

Czy wiemy, dlaczego tak jest? Ponadto czy sekcja CDATA będzie nadal pobierana przez przeglądarkę, która renderuje niektóre z tych danych? Mam kilka tagów HTML w swoich tagach XML i potrzebuję ich renderowania dla użytkownika końcowego w celu użycia narzędzia do edycji.
sulimmesh

11

Spróbuj najpierw wyczyścić kod HTML za pomocą tej funkcji:

$html = htmlspecialchars($html);

Znaki specjalne są zwykle reprezentowane inaczej w HTML i może to być mylące dla kompilatora. Jak &się stanie &amp;.


Czy ktoś może wyjaśnić, dlaczego jest to odrzucane? htmlspecialchars()to dokładna funkcja do konwersji &, ", <, >znaków w danych elementu.
JacobRossDev

7
Ta odpowiedź jest odrzucana, ponieważ nie działa dobrze w tym przypadku. Użycie tej funkcji całkowicie zepsuje Twój XML, konwertując „<” na „& lt;”. Nie znam żadnego sposobu, w jaki można użyć htmlspecialchars()i nie złamać XML. Wypróbowałem kilka flag i mój XML nadal się zepsuł.
Alex Finnarn

1
Powinieneś używać htmlspecialcharsna treści tagu xml, a nie na całym XML
gbalduzzi

7

Używam wersji łączonej:

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

1
Ten działa doskonale. Po prostu brakuje końcowego prawego nawiasu
myh34d

7

PROBLEM

  • Funkcja PHP simplexml_load_filegeneruje błąd analizy parser error : xmlParseEntityRefpodczas próby załadowania pliku XML z adresu URL.

PRZYCZYNA

  • Kod XML zwrócony przez adres URL nie jest prawidłowym kodem XML. Zawiera &wartość zamiast &amp;. Jest całkiem możliwe, że są inne błędy, które nie są oczywiste w tym momencie.

RZECZY POZA NASZĄ KONTROLĄ

  • W idealnym przypadku powinniśmy upewnić się, że prawidłowy plik XML jest podawany do simplexml_load_filefunkcji PHP , ale wygląda na to, że nie mamy żadnej kontroli nad sposobem tworzenia XML.
  • Nie można również wymusić simplexml_load_fileprzetwarzania nieprawidłowego pliku XML. Nie pozostawia nam to wielu opcji poza naprawą samego pliku XML.

MOŻLIWE ROZWIĄZANIE

Konwertuj nieprawidłowy XML na prawidłowy XML. Można to zrobić za pomocą PHP tidy extension. Dalsze instrukcje można znaleźć pod adresem http://php.net/manual/en/book.tidy.php

Po upewnieniu się, że rozszerzenie istnieje lub jest zainstalowane, wykonaj następujące czynności.

/**
 * 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);

UWAGA

Deweloper powinien spróbować porównać nieprawidłowy plik XML z prawidłowym kodem XML (wygenerowanym przez tidy), aby zobaczyć, że po użyciu tidy nie ma żadnych niepożądanych skutków ubocznych. Tidy wykonuje bardzo dobrą robotę, robiąc to poprawnie, ale nigdy nie boli zobaczyć go wizualnie i mieć 100% pewności. W naszym przypadku powinno to być tak proste, jak porównanie $ xml z $ tidy.


6

XML jest nieprawidłowy.

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

CDATA należy zawinąć wokół wszystkich specjalnych znaków XML, zgodnie z W3C



1

To rozwiązuje mój problem:

$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))));

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.