Cảnh báo 'xmlParseEntityRef: no name' khi tải xml vào tệp php


89

Tôi đang đọc một xml trong php bằng cách sử dụng simplexml_load_file. Tuy nhiên, trong khi cố gắng tải xml, nó sẽ hiển thị một danh sách các cảnh báo

Warning: simplexml_load_file() [function.simplexml-load-file]: <project orderno="6" campaign_name="International Relief & Development" project in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

Warning: simplexml_load_file() [function.simplexml-load-file]: ional Relief & Development" project_id="313" client_name="International Relief & in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

Làm cách nào để khắc phục để loại bỏ những cảnh báo này?

(XML được tạo từ url http://..../index.php/site/projectsvà được tải vào một biến trong test.php. Tôi không có quyền ghi đặc quyền vào index.php)


XML không hợp lệ. Bạn có thể hoàn toàn không tải được. Các lỗi có thể được khắc phục bằng cách thêm @vào phía trước simplexml_load_filehoặc bằng cách thêm cờ, xem trang hướng dẫn sử dụng simplexml_load_fileđể biết thêm thông tin và vui lòng xóa câu hỏi của bạn, câu hỏi này trùng lặp.
hakre

Tôi có thể thấy rằng câu trả lời của tôi đang nhận được khá nhiều sự chú ý, nếu đó thực sự là giải pháp: bạn có thể gắn cờ nó là "câu trả lời đúng" không? cảm ơn.
ricricucit

Câu trả lời:


143

XML rất có thể không hợp lệ.

Vấn đề có thể là "&"

$text=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $text);

sẽ loại bỏ "&" và thay thế bằng phiên bản mã HTML của nó ... hãy thử.


2
Cảm ơn bạn. Bạn đã cứu ngày của tôi!
Saim

2
Cách tốt nhất khi làm việc với XML là để đảm bảo không có ký tự mâu thuẫn và bạn nên thay thế chúng trước khi parsin
Ông Megamind

2
cảm ơn, điểm chính của câu hỏi này là vì xml không hợp lệ
yussan

Chỉ cần bổ sung một chút, nếu bạn muốn thay thế tất cả các ký hiệu và, hãy thêm 'g' vào regex của bạn. Giải pháp cập nhật sẽ giống như sau: $text=preg_replace('/&(?!#?[a-z0-9]+;)/g', '&amp;', $text);
flaming.codes

81

Tìm thấy cái này ở đây ...

Sự cố: Trình phân tích cú pháp XML trả về lỗi “xmlParseEntityRef: noname”

Nguyên nhân: Có một dấu '&' (ký tự dấu và) lạc ở đâu đó trong văn bản XML, ví dụ. một số văn bản và một số văn bản khác

Giải pháp:

  • Giải pháp 1: Loại bỏ dấu và.
  • Giải pháp 2: Mã hóa dấu và (nghĩa là thay thế &ký tự bằng &amp;). Hãy nhớ Giải mã khi đọc văn bản XML.
  • Giải pháp 3: Sử dụng các phần CDATA (văn bản bên trong phần CDATA sẽ bị trình phân tích cú pháp bỏ qua.) Ví dụ. <! [CDATA [một số văn bản và một số văn bản khác]]>

Lưu ý: '&' '<' '>' sẽ gây ra sự cố nếu không được xử lý đúng cách.


9
Điều này đã cứu tôi ngày hôm nay.
Bwire

Chúng ta có biết tại sao lại như vậy không? Ngoài ra, một phần CDATA có còn được chọn bởi một trình duyệt sẽ hiển thị một số dữ liệu này không? Tôi có một số thẻ HTML bên trong các thẻ XML của mình và tôi cần chúng được hiển thị cho người dùng cuối để làm công cụ chỉnh sửa.
sulimmesh

11

Trước tiên, hãy thử làm sạch HTML bằng chức năng này:

$html = htmlspecialchars($html);

Các ký tự đặc biệt thường được biểu diễn khác nhau trong HTML và nó có thể gây nhầm lẫn cho trình biên dịch. Giống như &trở thành &amp;.


Ai đó có thể giải thích tại sao điều này bị phản đối? htmlspecialchars()là hàm chính xác để chuyển đổi các &, ", <, >ký tự trong dữ liệu phần tử.
JacobRossDev

7
Câu trả lời này bị phản đối vì nó không hoạt động tốt trong trường hợp này. Việc sử dụng hàm đó sẽ phá vỡ hoàn toàn XML của bạn bằng cách chuyển đổi "<" thành "& lt;". Tôi không biết về bất kỳ cách nào mà bạn có thể sử dụng htmlspecialchars()và không phá vỡ XML. Tôi đã thử một vài cờ và XML của tôi vẫn bị hỏng.
Alex Finnarn

1
Bạn nên sử dụng htmlspecialcharstrên nội dung của một thẻ xml, không phải trên XML toàn
gbalduzzi

7

Tôi sử dụng phiên bản kết hợp:

strip_tags(preg_replace("/&(?!#?[a-z0-9]+;)/", "&amp;",$textorhtml))

1
Cái này đang hoạt động hoàn hảo. Bạn chỉ thiếu dấu ngoặc phải kết thúc
myh34d

7

VẤN ĐỀ

  • Hàm PHP simplexml_load_fileđang gặp lỗi phân tích cú pháp parser error : xmlParseEntityRefkhi cố gắng tải tệp XML từ một URL.

NGUYÊN NHÂN

  • XML được URL trả về không phải là XML hợp lệ. Nó chứa &giá trị thay vì &amp;. Rất có thể có các lỗi khác không rõ ràng tại thời điểm này.

NHỮNG ĐIỀU NGOÀI SỰ KIỂM SOÁT CỦA CHÚNG TÔI

  • Tốt nhất, chúng ta nên đảm bảo rằng một XML hợp lệ được cấp vào PHP simplexml_load_file hàm , nhưng có vẻ như chúng ta không có bất kỳ quyền kiểm soát nào đối với cách tạo XML.
  • Cũng không thể ép simplexml_load_file xử lý tệp XML không hợp lệ. Nó không để lại cho chúng tôi nhiều tùy chọn, ngoài việc sửa chính tệp XML.

GIẢI PHÁP KHẢ NĂNG

Chuyển đổi XML không hợp lệ thành XML hợp lệ. Nó có thể được thực hiện bằng cách sử dụngPHP tidy extension . Có thể tìm thêm hướng dẫn từ http://php.net/manual/en/book.tidy.php

Khi bạn chắc chắn rằng tiện ích mở rộng tồn tại hoặc đã được cài đặt, hãy thực hiện như sau.

/**
 * As per the question asked, the URL is loaded into a variable first, 
 * which we can assume to be $xml
 */
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<project orderno="6" campaign_name="International Relief & Development for under developed nations">
    <invalid-data>Some other data containing & in it</invalid-data>
    <unclosed-tag>
</project>
XML;

/**
 * Whenever we use tidy it is best to pass some configuration options 
 * similar to $tidyConfig. In this particular case we are making sure that
 * tidy understands that our input and output is XML.
 */
$tidyConfig = array (
    'indent' => true,
    'input-xml' => true, 
    'output-xml' => true,
    'wrap' => 200
);

/**
 * Now we can use tidy to parse the string and then repair it.
 */
$tidy = new tidy;
$tidy->parseString($xml, $tidyConfig, 'utf8');
$tidy->cleanRepair();

/**
 * If we try to output the repaired XML string by echoing $tidy it should look like. 

 <?xml version="1.0" encoding="utf-8"?>
 <project orderno="6" campaign_name="International Relief &amp; Development for under developed nations">
      <invalid-data>Some other data containing &amp; in it</invalid-data>
      <unclosed-tag></unclosed-tag>
 </project> 

 * As you can see that & is now fixed in campaign_name attribute 
 * and also with-in invalid-data element. You can also see that the   
 * <unclosed-tag> which didn't had a close tag, has been fixed too.
 */
echo $tidy;

/**
 * Now when we try to use simplexml_load_string to load the clean XML. When we
 * try to print_r it should look something like below.

 SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [orderno] => 6
            [campaign_name] => International Relief & Development for under developed nations
        )

    [invalid-data] => Some other data containing & in it
    [unclosed-tag] => SimpleXMLElement Object
        (
        )

)

 */
 $simpleXmlElement = simplexml_load_string($tidy);
 print_r($simpleXmlElement);

THẬN TRỌNG

Nhà phát triển nên thử so sánh XML không hợp lệ với một XML hợp lệ (được tạo bởi ngăn nắp), để xem không có tác dụng phụ nào sau khi sử dụng ngăn nắp. Tidy làm rất tốt việc thực hiện nó một cách chính xác, nhưng bạn sẽ không bao giờ thấy nó bằng mắt thường và chắc chắn 100%. Trong trường hợp của chúng tôi, nó sẽ đơn giản như so sánh $ xml với $ slim.


6

XML không hợp lệ.

<![CDATA[ 
{INVALID XML}
]]> 

CDATA phải được bao bọc xung quanh tất cả các ký tự XML đặc biệt, theo W3C



1

Điều này giải quyết vấn đề của tôi:

$description = strip_tags($value['Description']);
$description=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $description);
$description= preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $description);
$description=str_replace(' & ', ' &amp; ', html_entity_decode((htmlspecialchars_decode($description))));

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.