PHP: Wie gehe ich mit <! [CDATA [mit SimpleXMLElement um?

97

Mir ist aufgefallen, dass bei der Verwendung SimpleXMLElementeines Dokuments, das diese CDATA-Tags enthält, der Inhalt immer vorhanden ist NULL. Wie behebe ich das?

Entschuldigen Sie auch das Spammen über XML hier. Ich habe seit einigen Stunden versucht, ein XML-basiertes Skript zum Laufen zu bringen ...

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

Ich habe den ersten Treffer bei Google versucht, wenn Sie nach "SimpleXMLElement-CDs" suchen, aber das hat nicht funktioniert.

Angelo
quelle
Wie versuchen Sie, auf den Knotenwert zuzugreifen? Und ist SimpleXML eine Voraussetzung?
Allnightgrocery
Ich habe jede andere Funktion (xml2array und alle) ausprobiert, die ich im Web finden konnte, und SimpleXML scheint die einzige zu sein, die gute Ergebnisse liefert, außer dass die CDATA nicht funktioniert.
Angelo
1
Wir führen bei der Arbeit viel XML-Parsing mit DOMDocument ( php.net/manual/en/class.domdocument.php ) durch. Es funktioniert gut im Umgang mit CDATA. Geben Sie dem einen kurzen oder etwas mehr Code, damit wir sehen können, wie Sie mit SimpleXML arbeiten.
Allnightgrocery

Antworten:

181

Sie greifen wahrscheinlich nicht richtig darauf zu. Sie können es direkt ausgeben oder als Zeichenfolge umwandeln. (In diesem Beispiel ist das Casting überflüssig, da Echo es sowieso automatisch macht.)

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

Sie könnten besseres Glück haben mit LIBXML_NOCDATA:

$content = simplexml_load_string(
    '<content><![CDATA[Hello, world!]]></content>'
    , null
    , LIBXML_NOCDATA
);
Josh Davis
quelle
2
Nein, PHP überspringt CDATA aus irgendeinem Grund vollständig. Irgendwelche anderen Ideen?
Angelo
4
Dann ist es ein Fehler. Aktualisieren Sie PHP / libxml, bis es funktioniert (ich hatte noch nie Probleme mit CDATA und SimpleXML.) Andernfalls möchten Sie vielleicht Ihr Glück mit LIBXML_NOCDATA versuchen.
Josh Davis
5
Ich weiß, dass dies eine alte Antwort ist, aber ich möchte betonen, dass der erste Teil dieser Antwort richtig ist . Wenn Sie das Ergebnis mit drucken, print_rgreifen Sie tatsächlich nicht richtig darauf zu. Schreiben Sie den Code, den Sie tatsächlich wollen - wahrscheinlich mit echooder mit einer (string)Besetzung, und Sie werden feststellen, dass der Inhalt in Ordnung ist. Verwenden Sie nicht LIBXML_NOCDATA, es ist irrelevant.
IMSoP
7
@IMSoP Das Hinzufügen von LIBXML_NOCDATA (und das Ändern von nichts anderem) funktioniert, daher bin ich mir nicht sicher, ob es irrelevant ist.
Rand
3
@ SimonePalazzo XML besteht aus verschiedenen "Knoten" - z <anElement>a text node <aChildElement /> <![CDATA a cdata node]]> another text node</anElement>. Die CDATA- und Textknoten sind unterschiedliche Typen, und SimpleXML verfolgt dies, damit Sie das eingegebene XML zurückerhalten können. Wenn Sie ein SimpleXML-Objekt in ein Array drücken, werden viele Informationen weggeworfen - CDATA-Knoten, Kommentare, jedes Element nicht Im aktuellen Namespace (z. B. <someNSPrefix:someElement />) LIBXML_NOCDATAkonvertiert die Position des untergeordneten Elements im Text usw. CDATA-Knoten in Textknoten, behebt den Rest jedoch nicht.
IMSoP
48

Dies LIBXML_NOCDATAist ein optionaler dritter simplexml_load_file()Funktionsparameter. Dies gibt das XML-Objekt mit allen in Zeichenfolgen konvertierten CDATA-Daten zurück.

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


Korrigieren Sie CDATA in SimpleXML

Pradip Kharbuja
quelle
LIBXML_NOCDATA hat diese Arbeit für mich gemacht. PHP 5.3.5
Mike_K
1
Ihre Antwort erklärt die Bedeutung von LIBXML_NOCDATA , danke!
Marcio Mazzucato
14

Das hat den Trick für mich getan:

echo trim($entry->title);
Breez
quelle
Perfekt, wenn Sie die cdata (ohne LIBXML_NOCDATA) behalten müssen
maztch
10

Das funktioniert perfekt für mich.

$content = simplexml_load_string(
    $raw_xml
    , null
    , LIBXML_NOCDATA
);
Vijayrana
quelle
0

Wann verwenden LIBXML_NOCDATA?

Ich füge das Problem hinzu, wenn XML in JSON umgewandelt wird.

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

Beim Zugriff auf das SimpleXMLElement-Objekt erhält es die CDATA:

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

Ich mache Sinn, LIBXML_NOCDATAweil json_encodeich nicht auf das SimpleXMLElement zugreife, um die String-Casting-Funktion auszulösen. Ich vermute ein __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
quelle