PHP: Comment gérer <! [CDATA [avec SimpleXMLElement?

97

J'ai remarqué que lors de l'utilisation SimpleXMLElementsur un document contenant ces balises CDATA, le contenu est toujours NULL. Comment puis-je réparer ça?

Aussi, désolé pour le spam sur XML ici. J'essaie de faire fonctionner un script basé sur XML depuis plusieurs heures maintenant ...

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

J'ai essayé le premier hit sur Google si vous recherchez "SimpleXMLElement cdata", mais cela n'a pas fonctionné.

Angelo
la source
Comment essayez-vous d'accéder à la valeur du nœud? Et, SimpleXML est-il une exigence?
allnightgrocery
J'ai essayé toutes les autres fonctions (xml2array et tout) que j'ai pu trouver sur le Web et SimpleXML semble être la seule à donner de BONS résultats, à l'exception du CDATA qui ne fonctionne pas.
Angelo
1
Nous faisons beaucoup d' analyses XML au travail en utilisant DOMDocument ( php.net/manual/en/class.domdocument.php ). Cela fonctionne très bien dans la gestion de CDATA. Donnez-nous un court message ou publiez un peu plus de code pour que nous voyions comment vous travaillez avec SimpleXML.
allnightgrocery

Réponses:

182

Vous n'y accédez probablement pas correctement. Vous pouvez le sortir directement ou le convertir en chaîne. (dans cet exemple, le casting est superflu, car l'écho le fait de toute façon automatiquement)

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

Vous pourriez avoir plus de chance avec LIBXML_NOCDATA:

$content = simplexml_load_string(
    '<content><![CDATA[Hello, world!]]></content>'
    , null
    , LIBXML_NOCDATA
);
Josh Davis
la source
2
Non, PHP ignore complètement CDATA pour une raison quelconque. D'autres idées?
Angelo
4
Alors c'est un bug. Mettez à jour PHP / libxml jusqu'à ce que cela fonctionne (je n'ai jamais eu de problèmes avec CDATA et SimpleXML.) Sinon, vous voudrez peut-être tenter votre chance avec LIBXML_NOCDATA.
Josh Davis
5
Je sais que c'est une vieille réponse, mais je voudrais souligner que la première partie de cette réponse est correcte . Lorsque vous imprimez le résultat avec print_rvous n'y accédez en effet pas correctement. Écrivez le code que vous voulez réellement - probablement avec echoou avec un (string)casting, et vous constaterez que le contenu est correct. N'utilisez pas LIBXML_NOCDATA, cela n'est pas pertinent.
IMSoP
7
@IMSoP L'ajout de LIBXML_NOCDATA (et ne rien changer d'autre) fonctionne, donc je ne suis pas sûr que ce soit hors de propos.
rand
3
@SimonePalazzo XML se compose de différents "nœuds" - par exemple <anElement>a text node <aChildElement /> <![CDATA a cdata node]]> another text node</anElement>. Les nœuds CDATA et texte sont de types différents, et SimpleXML le suit afin que vous puissiez récupérer le XML que vous avez mis. Lorsque vous insérez un objet SimpleXML dans un tableau, il jette beaucoup d'informations - nœuds CDATA, commentaires, tout élément non dans l'espace de noms courant (par exemple <someNSPrefix:someElement />), la position de l'élément enfant dans le texte, etc. LIBXML_NOCDATAconvertit les nœuds CDATA en nœuds de texte, mais ne corrige pas le reste.
IMSoP
48

Le LIBXML_NOCDATAtroisième paramètre optionnel de la simplexml_load_file()fonction. Cela renvoie l'objet XML avec toutes les données CDATA converties en chaînes.

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


Correction de CDATA dans SimpleXML

Pradip Kharbuja
la source
LIBXML_NOCDATA est ce qui a fait que cela fonctionne pour moi. PHP 5.3.5
Mike_K
1
Votre réponse est celle qui explique la signification de LIBXML_NOCDATA , merci!
Marcio Mazzucato
14

Cela a fait l'affaire pour moi:

echo trim($entry->title);
brise
la source
Parfait si vous avez besoin de garder le cdata (sans LIBXML_NOCDATA)
maztch
10

Cela fonctionne parfaitement pour moi.

$content = simplexml_load_string(
    $raw_xml
    , null
    , LIBXML_NOCDATA
);
vijayrana
la source
0

Quand l'utiliser LIBXML_NOCDATA?

J'ajoute le problème lors de la transformation de XML en JSON.

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

Lors de l'accès à l'objet SimpleXMLElement, il obtient le CDATA:

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

J'ai du sens à utiliser LIBXML_NOCDATAcar json_encoden'accédez pas à SimpleXMLElement pour déclencher la fonction de casting de chaînes, je suppose un __toString()équivalent.

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>", null, LIBXML_NOCDATA);
echo json_encode($xml);
/*
 {
   "content": "Hello, world!"
 }
*/
Gabriel Glenn
la source