PHP: Làm thế nào để xử lý <! [CDATA [với SimpleXMLElement?


97

Tôi nhận thấy rằng khi sử dụng SimpleXMLElementtrên tài liệu có chứa các thẻ CDATA đó, nội dung luôn là như vậy NULL. Làm cách nào để sửa lỗi này?

Ngoài ra, xin lỗi vì đã gửi thư rác về XML ở đây. Tôi đã cố gắng làm cho một tập lệnh dựa trên XML hoạt động được vài giờ ...

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

Tôi đã thử lần truy cập đầu tiên trên Google nếu bạn tìm kiếm "SimpleXMLElement cdata", nhưng điều đó không hoạt động.


Bạn đang cố gắng truy cập giá trị nút như thế nào? Và, SimpleXML có phải là một yêu cầu không?
allnightgrocery

Tôi đã thử mọi chức năng khác (xml2array và tất cả) mà tôi có thể tìm thấy trên web và SimpleXML dường như là chức năng duy nhất mang lại kết quả TỐT, ngoại trừ CDATA không hoạt động.
Angelo

1
Chúng tôi thực hiện rất nhiều phân tích cú pháp XML tại nơi làm việc bằng DOMDocument ( php.net/manual/en/class.domdocument.php ). Nó hoạt động tốt trong việc xử lý CDATA. Cung cấp cho chúng tôi một đoạn ngắn hoặc đăng thêm một đoạn mã để chúng tôi biết cách bạn đang làm việc với SimpleXML.
allnightgrocery

Câu trả lời:


182

Có thể bạn đang truy cập không đúng cách. Bạn có thể xuất nó trực tiếp hoặc ép nó thành một chuỗi. (trong ví dụ này, quá trình truyền là không cần thiết, vì echo tự động vẫn thực hiện)

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

Bạn có thể gặp may mắn hơn với LIBXML_NOCDATA:

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

2
Không, PHP hoàn toàn bỏ qua CDATA vì một số lý do. Bất kỳ ý tưởng khác?
Angelo

4
Sau đó, nó là một lỗi. Nâng cấp PHP / libxml cho đến khi nó hoạt động (tôi chưa bao giờ gặp bất kỳ sự cố nào với CDATA và SimpleXML.) Bạn có thể muốn thử vận ​​may của mình với LIBXML_NOCDATA.
Josh Davis

5
Tôi biết đây là một câu trả lời cũ, nhưng tôi muốn nhấn mạnh rằng phần đầu tiên của câu trả lời này là đúng . Khi bạn in kết quả với print_rbạn, bạn thực sự không truy cập nó một cách chính xác. Viết mã bạn thực sự muốn - có thể với echohoặc với một (string)diễn viên, và bạn sẽ thấy nội dung ổn. Không sử dụng LIBXML_NOCDATA nó không liên quan.
IMSoP

7
@IMSoP Thêm LIBXML_NOCDATA (và không thay đổi gì khác) hoạt động, vì vậy tôi không chắc nó không liên quan.
rand

3
@SimonePalazzo XML bao gồm nhiều "nút" khác nhau - ví dụ <anElement>a text node <aChildElement /> <![CDATA a cdata node]]> another text node</anElement>. Các nút CDATA và nút văn bản là các loại khác nhau và SimpleXML theo dõi điều này để bạn có thể lấy lại XML bạn đã đưa vào. Khi bạn ép một đối tượng SimpleXML vào một mảng, nó sẽ ném đi rất nhiều thông tin - các nút CDATA, nhận xét, bất kỳ phần tử nào không trong không gian tên hiện tại (ví dụ <someNSPrefix:someElement />), vị trí của phần tử con trong văn bản, v.v. LIBXML_NOCDATAchuyển đổi các nút CDATA thành các nút văn bản, nhưng không sửa phần còn lại.
IMSoP

48

Các LIBXML_NOCDATAlà tùy chọn tham số thứ ba của simplexml_load_file()chức năng. Điều này trả về đối tượng XML với tất cả dữ liệu CDATA được chuyển đổi thành chuỗi.

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


Sửa lỗi CDATA trong SimpleXML


LIBXML_NOCDATA là những gì đã làm cho điều này làm việc cho tôi. PHP 5.3.5
Mike_K

1
Câu trả lời của bạn là câu giải thích ý nghĩa LIBXML_NOCDATA , cảm ơn!
Marcio Mazzucato

14

Điều này đã làm cho tôi mẹo:

echo trim($entry->title);

Hoàn hảo nếu bạn cần giữ cdata (không có LIBXML_NOCDATA)
maztch

10

Điều này đang làm việc hoàn hảo cho tôi.

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

0

Sử dụng khi LIBXML_NOCDATAnào?

Tôi thêm vấn đề khi chuyển đổi XML sang JSON.

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

Khi truy cập đối tượng SimpleXMLElement, Nó nhận được CDATA:

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

Tôi có lý khi sử dụng LIBXML_NOCDATAjson_encodekhông truy cập SimpleXMLElement để kích hoạt tính năng truyền chuỗi, tôi đoán là __toString()tương đương.

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>", null, LIBXML_NOCDATA);
echo json_encode($xml);
/*
 {
   "content": "Hello, world!"
 }
*/
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.