Avvisi "xmlParseEntityRef: no name" durante il caricamento di xml in un file php


89

Sto leggendo un xml in php usando simplexml_load_file. Tuttavia, durante il tentativo di caricare l'xml, viene visualizzato un elenco di avvisi

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

Come correggo per rimuovere questi avvisi?

(XML è generato da url http://..../index.php/site/projectse caricato in una variabile in test.php. Non ho privilegi di scrittura su index.php)


L'XML non è valido. Potresti non essere in grado di caricarlo affatto. Gli errori possono essere eliminati aggiungendo @prima simplexml_load_fileo aggiungendo un flag, vedere la pagina di manuale di simplexml_load_fileper maggiori informazioni e per favore elimina la tua domanda, è un duplicato.
hakre

Vedo che la mia risposta sta ricevendo molta attenzione, se questa è effettivamente la soluzione: puoi contrassegnarla come "risposta corretta"? Grazie.
ricricucit

Risposte:


143

L'XML molto probabilmente non è valido.

Il problema potrebbe essere il "&"

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

eliminerà la "&" e la sostituirà con la sua versione in codice HTML ... provalo.


2
Grazie. Mi hai salvato la giornata!
Saim

2
La migliore pratica quando si lavora con XML è assicurarsi che non vi siano caratteri in conflitto e che è necessario sostituirli prima dell'analisi
Mr Megamind

2
grazie, il punto principale di questa domanda è perché xml non è valido
yussan

Solo una piccola aggiunta, se vuoi sostituire tutte le e commerciali, aggiungi "g" alla tua regex. La soluzione aggiornata sarebbe simile a questa: $text=preg_replace('/&(?!#?[a-z0-9]+;)/g', '&amp;', $text);
flaming.codes

81

Trovato questo qui ...

Problema: un parser XML restituisce l'errore "xmlParseEntityRef: noname"

Causa: da qualche parte nel testo XML è presente una "&" (carattere e commerciale), ad es. del testo e dell'altro testo

Soluzione:

  • Soluzione 1: rimuovere la e commerciale.
  • Soluzione 2: codifica la e commerciale (ovvero sostituisci il &carattere con &amp;). Ricordarsi di decodificare durante la lettura del testo XML.
  • Soluzione 3: utilizzare le sezioni CDATA (il testo all'interno di una sezione CDATA verrà ignorato dal parser.) Es. <! [CDATA [testo e altro testo]]>

Nota: '&' '<' '>' daranno tutti problemi se non gestiti correttamente.


9
Questo mi ha salvato oggi.
Bwire

Sappiamo perché è così? Inoltre, una sezione CDATA verrà ancora rilevata da un browser che visualizzerà alcuni di questi dati? Ho alcuni tag HTML all'interno dei miei tag XML e ho bisogno che vengano visualizzati all'utente finale per uno strumento di modifica.
sulimmesh

11

Prova a pulire prima l'HTML usando questa funzione:

$html = htmlspecialchars($html);

I caratteri speciali sono solitamente rappresentati in modo diverso in HTML e potrebbero creare confusione per il compilatore. Come &diventa &amp;.


Qualcuno può spiegare perché questo è downvoted? htmlspecialchars()è la funzione precisa per convertire i &, ", <, >caratteri nei dati dell'elemento.
JacobRossDev

7
Questa risposta è sottovalutata perché in questo caso non funziona bene. L'utilizzo di questa funzione interromperà completamente il tuo XML convertendo "<" in "& lt;". Non sono a conoscenza di alcun modo in cui puoi usare htmlspecialchars()e non rompere XML. Ho provato alcuni flag e il mio XML si è ancora rotto.
Alex Finnarn

1
Dovresti usare htmlspecialcharssul contenuto di un tag xml, non sull'intero XML
gbalduzzi

7

Uso una versione combinata:

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

1
Questo funziona perfettamente. Ti manca solo la parentesi destra finale
myh34d

7

PROBLEMA

  • La funzione PHP simplexml_load_filegenera un errore di analisi parser error : xmlParseEntityRefdurante il tentativo di caricare il file XML da un URL.

CAUSA

  • XML restituito dall'URL non è un XML valido. Contiene &valore invece di &amp;. È del tutto possibile che ci siano altri errori che non sono ovvi in ​​questo momento.

COSE FUORI DAL NOSTRO CONTROLLO

  • Idealmente, dovremmo assicurarci che un XML valido sia inserito nella simplexml_load_filefunzione PHP , ma sembra che non abbiamo alcun controllo su come viene creato l'XML.
  • Inoltre, non è possibile forzare simplexml_load_filel'elaborazione di un file XML non valido. Non ci lascia molte opzioni, oltre a correggere il file XML stesso.

POSSIBILE SOLUZIONE

Converti XML non valido in XML valido. Può essere fatto usando PHP tidy extension. Ulteriori istruzioni possono essere trovate su http://php.net/manual/en/book.tidy.php

Una volta che sei sicuro che l'estensione esista o sia installata, procedi come segue.

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

ATTENZIONE

Lo sviluppatore dovrebbe provare a confrontare l'XML non valido con un XML valido (generato da tidy), per vedere che non ci sono effetti collaterali negativi dopo aver usato tidy. Tidy fa un ottimo lavoro nel farlo correttamente, ma non fa mai male vederlo visivamente ed essere sicuri al 100%. Nel nostro caso dovrebbe essere semplice come confrontare $ xml con $ tidy.


6

L'XML non è valido.

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

CDATA dovrebbe essere racchiuso attorno a tutti i caratteri XML speciali, come per W3C



1

Questo risolve il mio problema:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.