2009-08-13 8 views
11

Tôi tìm kiếm và xử lý các tệp XML từ nơi khác và cần phải chuyển đổi chúng bằng một số XSLT. Không vấn đề gì. Sử dụng thư viện PHP5 và thư viện DOM , mọi thứ đều nhanh chóng. Làm việc tốt, cho đến bây giờ. Hôm nay, funky ký tự nằm trong tệp XML - "thông minh" trích dẫn từ Word, có vẻ như thích. Dù sao, DOMDocument-> tải phàn nàn về họ, nói rằng họ không phải là UTF-8, và để xác định mã hóa.Làm cách nào để tôi biết DOMDocument-> load() mã hóa nào tôi muốn sử dụng?

Lo và xem, mã hóa không được chỉ định trong các tệp XML này. Nếu tôi thêm vào 'encoding = "iso-8859-1"' vào tiêu đề, nó hoạt động tốt. Chà là Tôi không kiểm soát được các tệp XML này.

Đọc tệp thành chuỗi, sửa đổi tiêu đề và viết lại vào vị trí khác có vẻ là lựa chọn duy nhất của tôi, nhưng tôi muốn làm mà không phải sử dụng bản sao tạm thời của tệp XML tại tất cả các. Có phải có cách nào đơn giản để nói cho trình phân tích cú pháp phân tích cú pháp chúng như thể chúng là iso-8859-1 không?

Trả lời

9

Tính năng này có phù hợp với bạn không?

$doc = new DOMDocument('1.0', 'iso-8859-1'); 
$doc->load($xmlPath); 

Edit: Kể từ khi nó xuất hiện rằng điều này không làm việc, những gì bạn có thể làm thay cũng tương tự như phương pháp hiện tại của bạn nhưng nếu không có các tập tin tạm thời. Đọc các tập tin XML từ nguồn của bạn chỉ sử dụng các hoạt động tiêu chuẩn IO (file_get_contents() hoặc một cái gì đó), sau đó thực hiện bất cứ điều gì thay đổi đối với mã hóa bạn cần (iconv() hoặc utf8_decode()) và sau đó sử dụng loadXML()

$myXMLString = file_get_contents($xmlPath); 
$myXMLString = utf8_decode($myXMLString); 
$doc = new DOMDocument('1.0', 'iso-8859-1'); 
$doc->loadXML($myXMLString); 
+1

Cố gắng này - nó dường như không ảnh hưởng đến các tài liệu được nạp - từ đọc sách của tôi, tôi 'm khá chắc chắn mã hóa được thiết lập lại bởi tải() gọi – Loki

5

tôi đã không tìm ra cách để đặt mã hóa mặc định (chưa) nhưng có thể chế độ khôi phục khả thi trong trường hợp này.
Khi libxml gặp lỗi mã hóa và không mã hóa nào được đặt rõ ràng, nó chuyển từ unicode/utf8 sang latin1 và tiếp tục phân tích cú pháp tài liệu. Nhưng trong bối cảnh phân tích cú pháp, thuộc tính wellFormed được đặt thành 0/false. Phần mở rộng DOM của PHP coi tài liệu là hợp lệ nếu wellFormed là đúng hoặc thuộc tính của đối tượng DOMDocument recover là đúng.

<?php 
// german Umlaut ä in latin1 = 0xE4 
$xml = '<foo>'.chr(0xE4).'</foo>'; 

$doc = new DOMDocument; 
$b = $doc->loadxml($xml); 
echo 'with doc->recover=false(default) : ', ($b) ? 'success':'failed', "\n"; 

$doc = new DOMDocument; 
$doc->recover = true; 
$b = $doc->loadxml($xml); 
echo 'with doc->recover=true : ', ($b) ? 'success':'failed', "\n"; 

in

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding ! 
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 6 
with doc->recover=false(default) : failed 

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding ! 
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 11 
with doc->recover=true : success 

Bạn vẫn nhận được thông báo cảnh báo (có thể bị ức chế với @ $ doc-> load()) và nó cũng sẽ hiển thị trong internal libxml errors (chỉ một lần khi trình phân tích cú pháp từ utf8 sang latin1). Mã lỗi cho lỗi cụ thể này sẽ là 9 (XML_ERR_INVALID_CHAR).

<?php 
$xml = sprintf('<foo> 
    <ae>%s</ae> 
    <oe>%s</oe> 
    & 
</foo>', chr(0xE4),chr(0xF6)); 

libxml_use_internal_errors(true); 
$doc = new DOMDocument; 
$doc->recover = true; 
libxml_clear_errors(); 
$b = $doc->loadxml($xml); 
$invalidCharFound = false; 
foreach(libxml_get_errors() as $error) { 
    if (9==$error->code && !$invalidCharFound) { 
     $invalidCharFound = true; 
     echo "found invalid char, possibly harmless\n"; 
    } 
    else { 
     echo "hm, that's probably more severe: ", $error->message, "\n"; 
    } 
} 
2

Cách ony để xác định mã hóa là trong khai báo XML vào lúc bắt đầu của tập tin:

<?xml version="1.0" encoding="ISO-8859-1"?> 
+0

Đây là câu trả lời đúng chỉ - xem thêm http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8- đúng – iquito