PHP: come gestire <! [CDATA [con SimpleXMLElement?


97

Ho notato che quando si utilizza SimpleXMLElementsu un documento che contiene quei tag CDATA, il contenuto è sempre NULL. Come lo risolvo?

Inoltre, ci scusiamo per lo spamming su XML qui. Ho provato a far funzionare uno script basato su XML per diverse ore ormai ...

<content><![CDATA[Hello, world!]]></content>

Ho provato il primo colpo su Google se cercavi "SimpleXMLElement cdata", ma non ha funzionato.


Come stai cercando di accedere al valore del nodo? E SimpleXML è un requisito?
allnightgrocery

Ho provato tutte le altre funzioni (xml2array e tutte) che sono riuscito a trovare sul web e SimpleXML sembra essere l'unica che dà buoni risultati, tranne per il CDATA che non funziona.
Angelo

1
Facciamo un sacco di analisi XML al lavoro usando DOMDocument ( php.net/manual/en/class.domdocument.php ). Funziona perfettamente nella gestione di CDATA. Dacci un breve o pubblica un po 'più di codice per farci vedere come stai lavorando con SimpleXML.
allnightgrocery

Risposte:


182

Probabilmente non stai accedendo correttamente. Puoi visualizzarlo direttamente o eseguirne il cast come stringa. (in questo esempio, il casting è superfluo, poiché l'eco lo fa comunque automaticamente)

$content = simplexml_load_string(
    '<content><![CDATA[Hello, world!]]></content>'
);
echo (string) $content;

// or with parent element:

$foo = simplexml_load_string(
    '<foo><content><![CDATA[Hello, world!]]></content></foo>'
);
echo (string) $foo->content;

Potresti avere più fortuna con LIBXML_NOCDATA:

$content = simplexml_load_string(
    '<content><![CDATA[Hello, world!]]></content>'
    , null
    , LIBXML_NOCDATA
);

2
No, PHP salta completamente CDATA per qualche motivo. Altre idee?
Angelo

4
Allora è un bug. Aggiorna PHP / libxml finché non funziona (non ho mai avuto problemi con CDATA e SimpleXML.) Altrimenti potresti tentare la fortuna con LIBXML_NOCDATA.
Josh Davis

5
So che questa è una vecchia risposta, ma vorrei sottolineare che la prima parte di questa risposta è corretta . Quando si stampa il risultato con non print_rsi sta effettivamente accedendo correttamente. Scrivi il codice che desideri effettivamente, probabilmente con echoo con un (string)cast, e scoprirai che il contenuto va bene. Non utilizzare LIBXML_NOCDATA è irrilevante.
IMSoP

7
@IMSoP L'aggiunta di LIBXML_NOCDATA (e la modifica di nient'altro) funziona, quindi non sono così sicuro che sia irrilevante.
rand

3
@SimonePalazzo XML è costituito da vari "nodi" diversi - es <anElement>a text node <aChildElement /> <![CDATA a cdata node]]> another text node</anElement>. I nodi CDATA e di testo sono di tipi diversi e SimpleXML ne tiene traccia in modo da poter recuperare l'XML che hai inserito. Quando comprimi un oggetto SimpleXML in un array, butta via molte informazioni: nodi CDATA, commenti, qualsiasi elemento non nello spazio dei nomi corrente (ad esempio <someNSPrefix:someElement />), la posizione dell'elemento figlio nel testo, ecc. LIBXML_NOCDATAconverte i nodi CDATA in nodi di testo, ma non risolve il resto.
IMSoP

48

Il LIBXML_NOCDATAterzo parametro di simplexml_load_file()funzione è opzionale . Ciò restituisce l'oggetto XML con tutti i dati CDATA convertiti in stringhe.

$xml = simplexml_load_file($this->filename, 'SimpleXMLElement', LIBXML_NOCDATA);
echo "<pre>";
print_r($xml);
echo "</pre>";


Correggi CDATA in SimpleXML


LIBXML_NOCDATA è ciò che ha fatto funzionare questo per me. PHP 5.3.5
Mike_K

1
La tua risposta è quella che spiega il significato di LIBXML_NOCDATA , grazie!
Marcio Mazzucato

14

Questo ha fatto il trucco per me:

echo trim($entry->title);

Perfetto se devi conservare i cdata (senza LIBXML_NOCDATA)
maztch

10

Funziona perfettamente per me.

$content = simplexml_load_string(
    $raw_xml
    , null
    , LIBXML_NOCDATA
);

0

Quando usarlo LIBXML_NOCDATA?

Aggiungo il problema durante la trasformazione di XML in JSON.

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>");
echo json_encode($xml, true); 
/* prints
   {
     "content": {}
   }
 */

Quando si accede all'oggetto SimpleXMLElement, ottiene il CDATA:

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>");
echo $xml->content; 
/* prints
   Hello, world!
*/

Ho senso da usare LIBXML_NOCDATAperché json_encodenon accedi a SimpleXMLElement per attivare la funzione di casting delle stringhe, immagino un __toString()equivalente.

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>", null, LIBXML_NOCDATA);
echo json_encode($xml);
/*
 {
   "content": "Hello, world!"
 }
*/
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.