PHP: Bagaimana menangani <! [CDATA [dengan SimpleXMLElement?

97

Saya perhatikan bahwa saat menggunakan SimpleXMLElementpada dokumen yang berisi tag CDATA tersebut, isinya selalu NULL. Bagaimana cara mengatasinya?

Juga, maaf telah mengirim spam tentang XML di sini. Saya telah mencoba membuat skrip berbasis XML berfungsi selama beberapa jam sekarang ...

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

Saya mencoba klik pertama di Google jika Anda mencari "SimpleXMLElement cdata", tetapi tidak berhasil.

Angelo
sumber
Bagaimana Anda mencoba mengakses nilai node? Dan, apakah SimpleXML merupakan persyaratan?
allnightgrocery
Saya mencoba setiap fungsi lain (xml2array dan semua) yang dapat saya temukan di web dan SimpleXML tampaknya menjadi satu-satunya yang memberikan hasil yang BAIK, kecuali CDATA yang tidak berfungsi.
Angelo
1
Kami melakukan banyak parsing XML saat bekerja menggunakan DOMDocument ( php.net/manual/en/class.domdocument.php ). Ia bekerja dengan baik dalam menangani CDATA. Berikan penjelasan singkat atau posting sedikit kode lagi agar kami dapat melihat bagaimana Anda bekerja dengan SimpleXML.
allnightgrocery

Jawaban:

182

Anda mungkin tidak mengaksesnya dengan benar. Anda dapat mengeluarkannya secara langsung atau mentransmisikannya sebagai string. (dalam contoh ini, casting tidak berguna, karena echo secara otomatis melakukannya)

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

Anda mungkin lebih beruntung dengan LIBXML_NOCDATA:

$content = simplexml_load_string(
    '<content><![CDATA[Hello, world!]]></content>'
    , null
    , LIBXML_NOCDATA
);
Josh Davis
sumber
2
Tidak, PHP melewatkan CDATA sepenuhnya karena alasan tertentu. Ada ide lain?
Angelo
4
Maka itu adalah bug. Tingkatkan PHP / libxml hingga berfungsi (saya tidak pernah mengalami masalah dengan CDATA dan SimpleXML.) Anda mungkin ingin mencoba keberuntungan dengan LIBXML_NOCDATA jika tidak.
Josh Davis
5
Saya tahu ini adalah jawaban lama, tetapi saya ingin menekankan bahwa bagian pertama dari jawaban ini benar . Saat Anda mencetak hasilnya dengan print_rAnda memang tidak mengaksesnya dengan benar. Tulis kode yang Anda inginkan - mungkin dengan echo, atau dengan (string)pemeran, dan Anda akan menemukan isinya baik-baik saja. Jangan gunakan LIBXML_NOCDATA itu tidak relevan.
IMSoP
7
@IMSoP Menambahkan LIBXML_NOCDATA (dan tidak mengubah yang lain) berfungsi, jadi saya tidak begitu yakin itu tidak relevan.
rand
3
@SimonePalazzo XML terdiri dari berbagai "node" yang berbeda - mis <anElement>a text node <aChildElement /> <![CDATA a cdata node]]> another text node</anElement>. Node CDATA dan teks adalah jenis yang berbeda, dan SimpleXML melacaknya sehingga Anda bisa mendapatkan kembali XML yang Anda masukkan. Saat Anda memasukkan objek SimpleXML ke dalam larik, ia membuang banyak informasi - simpul CDATA, komentar, elemen apa pun tidak di namespace saat ini (misalnya <someNSPrefix:someElement />), posisi elemen anak dalam teks, dll. LIBXML_NOCDATAmengubah node CDATA menjadi node teks, tetapi tidak memperbaiki sisanya.
IMSoP
48

Ini LIBXML_NOCDATAadalah parameter simplexml_load_file()fungsi ketiga opsional . Ini mengembalikan objek XML dengan semua data CDATA diubah menjadi string.

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


Perbaiki CDATA di SimpleXML

Pradip Kharbuja
sumber
LIBXML_NOCDATA yang membuat ini berhasil untuk saya. PHP 5.3.5
Mike_K
1
Jawaban anda adalah salah satu yang menjelaskan arti dari LIBXML_NOCDATA , terima kasih!
Marcio Mazzucato
14

Ini melakukan trik untuk saya:

echo trim($entry->title);
semilir
sumber
Sempurna jika Anda perlu menyimpan cdata (tanpa LIBXML_NOCDATA)
maztch
10

Ini bekerja sempurna untuk saya.

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

Kapan digunakan LIBXML_NOCDATA?

Saya menambahkan masalah saat mengubah XML ke JSON.

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

Saat mengakses objek SimpleXMLElement, Ia mendapatkan CDATA:

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

Saya masuk akal untuk digunakan LIBXML_NOCDATAkarena json_encodetidak mengakses SimpleXMLElement untuk memicu fitur pengecoran string, saya menebak yang __toString()setara.

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