PHP: วิธีจัดการ <! [CDATA [ด้วย SimpleXMLElement?


100

ผมสังเกตเห็นว่าเมื่อใช้SimpleXMLElementในเอกสารที่มีแท็ก CDATA NULLเหล่านั้นเนื้อหาอยู่เสมอ ฉันจะแก้ไขปัญหานี้ได้อย่างไร

นอกจากนี้ขออภัยสำหรับสแปมเกี่ยวกับ XML ที่นี่ ฉันพยายามทำให้สคริปต์ที่ใช้ XML ทำงานได้หลายชั่วโมงแล้ว ...

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

ฉันลองใช้ Hit แรกใน Google หากคุณค้นหา "SimpleXMLElement cdata" แต่ไม่ได้ผล


คุณพยายามเข้าถึงค่าโหนดอย่างไร และ SimpleXML เป็นข้อกำหนดหรือไม่?
allnightgrocery

ฉันลองใช้ฟังก์ชันอื่น ๆ ทั้งหมด (xml2array และทั้งหมด) ที่ฉันสามารถหาได้บนเว็บและ SimpleXML ดูเหมือนจะเป็นฟังก์ชันเดียวที่ให้ผลลัพธ์ที่ดียกเว้น CDATA ไม่ทำงาน
Angelo

1
เราทำการแยกวิเคราะห์ XML จำนวนมากในที่ทำงานโดยใช้ DOMDocument ( php.net/manual/en/class.domdocument.php ) ใช้งานได้ดีในการจัดการ CDATA ให้รหัสสั้น ๆ หรือโพสต์รหัสเพิ่มเติมเล็กน้อยเพื่อให้เราเห็นว่าคุณทำงานกับ SimpleXML อย่างไร
allnightgrocery

คำตอบ:


184

คุณอาจเข้าถึงไม่ถูกต้อง คุณสามารถส่งออกโดยตรงหรือส่งเป็นสตริง (ในตัวอย่างนี้การแคสต์นั้นไม่จำเป็นเนื่องจากเสียงสะท้อนจะทำโดยอัตโนมัติ)

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

คุณอาจโชคดีกว่ากับLIBXML_NOCDATA:

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

3
ไม่ PHP ข้าม CDATA อย่างสมบูรณ์ด้วยเหตุผลบางประการ ความคิดอื่น ๆ ?
Angelo

4
จากนั้นก็เป็นจุดบกพร่อง อัปเกรด PHP / libxml จนกว่าจะใช้งานได้ (ฉันไม่เคยมีปัญหากับ CDATA และ SimpleXML เลย) คุณอาจต้องการลองเสี่ยงโชคกับ LIBXML_NOCDATA เป็นอย่างอื่น
Josh Davis

5
ฉันรู้ว่านี้เป็นคำตอบที่เก่า แต่ผมอยากจะเน้นว่าส่วนแรกของคำตอบนี้ถูกต้อง เมื่อคุณพิมพ์ผลลัพธ์โดยที่print_rคุณไม่สามารถเข้าถึงได้อย่างถูกต้อง เขียนโค้ดที่คุณต้องการจริง ๆ อาจจะมีechoหรือแบบ(string)นักแสดงแล้วคุณจะพบว่าเนื้อหานั้นดี อย่าใช้ LIBXML_NOCDATA มันไม่เกี่ยวข้อง
IMSoP

7
@IMSoP การเพิ่ม LIBXML_NOCDATA (และเปลี่ยนอะไรอีก) ใช้งานได้ดังนั้นฉันไม่แน่ใจว่ามันไม่เกี่ยวข้อง
แรนด์

3
XML @SimonePalazzo ประกอบด้วยต่างๆที่แตกต่างกัน "โหน" - <anElement>a text node <aChildElement /> <![CDATA a cdata node]]> another text node</anElement>เช่น CDATA และโหนดข้อความเป็นประเภทที่แตกต่างกันและ SimpleXML ติดตามสิ่งนี้เพื่อให้คุณสามารถเรียกคืน XML ที่คุณใส่ไว้ได้เมื่อคุณบีบวัตถุ SimpleXML ลงในอาร์เรย์มันจะพ่นข้อมูลจำนวนมากออกไปไม่ว่าจะเป็นโหนด CDATA ความคิดเห็นองค์ประกอบใด ๆ ในเนมสเปซปัจจุบัน (เช่น<someNSPrefix:someElement />) ตำแหน่งขององค์ประกอบลูกในข้อความ ฯลฯLIBXML_NOCDATAแปลงโหนด CDATA เป็นโหนดข้อความ แต่ไม่ได้แก้ไขส่วนที่เหลือ
IMSoP

52

LIBXML_NOCDATAเป็นพารามิเตอร์ที่สามที่ไม่จำเป็นของsimplexml_load_file()ฟังก์ชั่น สิ่งนี้จะส่งคืนอ็อบเจ็กต์ XML พร้อมข้อมูล CDATA ทั้งหมดที่แปลงเป็นสตริง

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


แก้ไข CDATA ใน SimpleXML


LIBXML_NOCDATA คือสิ่งที่ทำให้งานนี้สำหรับฉัน PHP 5.3.5
Mike_K

1
คำตอบของคุณคือคำตอบที่อธิบายความหมายของLIBXML_NOCDATAขอบคุณ!
Marcio Mazzucato

14

นี้ได้เคล็ดลับสำหรับฉัน:

echo trim($entry->title);

สมบูรณ์แบบถ้าคุณต้องการเก็บ cdata (โดยไม่มี LIBXML_NOCDATA)
maztch

แสดงเป็นคำตอบของคำถามได้ไหม
Peter Højlund Andersen


0

ใช้เมื่อไหร่LIBXML_NOCDATA?

ฉันเพิ่มปัญหาเมื่อเปลี่ยน XML เป็น JSON

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

เมื่อเข้าถึงวัตถุ SimpleXMLElement จะได้รับ CDATA:

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

ฉันมีเหตุผลที่จะใช้LIBXML_NOCDATAเพราะjson_encodeไม่ได้เข้าถึง SimpleXMLElement เพื่อเรียกใช้คุณสมบัติการส่งสตริงฉันเดาว่า__toString()เทียบเท่า

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>", null, LIBXML_NOCDATA);
echo json_encode($xml);
/*
 {
   "content": "Hello, world!"
 }
*/
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.