2010-02-14 25 views
7

Tôi cần tải một tài liệu XML vào PHP đến từ một nguồn bên ngoài. XML không khai báo mã hóa của nó và chứa các ký tự không hợp lệ như &. Nếu tôi cố gắng tải tài liệu XML trực tiếp trong trình duyệt, tôi gặp lỗi như "Một ký tự không hợp lệ được tìm thấy trong nội dung văn bản" cũng khi tải tệp trong PHP, tôi nhận được rất nhiều cảnh báo như: xmlParseEntityRef: no name in EntityInput is not proper UTF-8, indicate encoding ! Bytes: 0x9C 0x31 0x21 0x3C.Sửa XML không đúng định dạng trong PHP trước khi xử lý bằng cách sử dụng các hàm DOMDocument

Rõ ràng là XML không được định dạng đúng và chứa các ký tự không hợp lệ cần được chuyển đổi thành các thực thể XML.

Điều này là do nguồn cấp dữ liệu XML được tạo thành từ dữ liệu do nhiều người dùng khác cung cấp và rõ ràng nó không được xác thực hoặc định dạng lại trước khi tôi nhận được.

Tôi đã nói chuyện với nhà cung cấp nguồn cấp dữ liệu XML và họ nói rằng họ đang cố gắng để các nhà cung cấp nội dung phân loại nó, nhưng điều này có vẻ ngớ ngẩn vì họ phải xác thực đầu vào trước. Về cơ bản, tôi cần sửa chữa XML sửa bất kỳ lỗi mã hóa nào và chuyển đổi bất kỳ ký tự không hợp lệ nào thành các thực thể XML sao cho XML tải vấn đề khi sử dụng các hàm DOMDocument của PHP.

Mã của tôi hiện trông giống như:

$feedURL = '3704017_14022010_050004.xml'; 
    $dom = new DOMDocument(); 
    $dom->load($feedURL); 

Ví dụ tập tin XML cho thấy vấn đề mã hóa (nhấp vào để tải): feed.xml

Ví dụ XML chứa ký tự chưa được chuyển đổi sang đơn vị XML:

<?xml version="1.0"?> 
<feed> 
<RECORD> 
<ID>117387</ID> 
<ADVERTISERNAME>Test</ADVERTISERNAME> 
<AID>10544740</AID> 
<NAME>This & This</NAME> 
<DESCRIPTION>For one day only this is > than this.</DESCRIPTION> 
</RECORD> 
</feed> 
+3

"Làm thế nào để tất cả các khách hàng hài lòng khác (?) Đối phó với dữ liệu và tại sao tôi là người duy nhất khốn khổ" - đó là câu hỏi tôi muốn hỏi nhà cung cấp. Bạn có thể cung cấp một tài liệu ví dụ (chính xác) không? – VolkerK

+0

Tôi đã tự hỏi bản thân mình.Tôi đã nói chuyện với họ và họ nói với tôi rằng họ đang gặp vấn đề về chất lượng dữ liệu và đã yêu cầu các nhà cung cấp nội dung phân loại nó. Tôi giả định rằng các khách hàng khác đã tìm thấy cách sửa lỗi nguồn cấp dữ liệu XML trước khi họ cố xử lý nó. Do đó câu hỏi của tôi. – Camsoft

+0

@VolkerK Tôi đã tải lên một tập con của toàn bộ tài liệu XML dưới dạng XML đầy đủ với hơn 42.000 dòng. – Camsoft

Trả lời

8

Hãy thử sử dụng thư viện Tidy có thể được sử dụng để làm sạch HTML và XML kém http://php.net/manual/en/book.tidy.php

Một giải pháp PHP tinh khiết để sửa chữa một số XML như thế này:

<?xml version="1.0"?> 
<feed> 
<RECORD> 
<ID>117387</ID> 
<ADVERTISERNAME>Test < texter</ADVERTISERNAME> 
<AID>10544740</AID> 
<NAME>This & This</NAME> 
<DESCRIPTION>For one day only this is > than this.</DESCRIPTION> 
</RECORD> 
</feed> 

Sẽ là một cái gì đó như thế này:

function cleanupXML($xml) { 
    $xmlOut = ''; 
    $inTag = false; 
    $xmlLen = strlen($xml); 
    for($i=0; $i < $xmlLen; ++$i) { 
     $char = $xml[$i]; 
     // $nextChar = $xml[$i+1]; 
     switch ($char) { 
     case '<': 
      if (!$inTag) { 
       // Seek forward for the next tag boundry 
       for($j = $i+1; $j < $xmlLen; ++$j) { 
       $nextChar = $xml[$j]; 
       switch($nextChar) { 
       case '<': // Means a < in text 
        $char = htmlentities($char); 
        break 2; 
       case '>': // Means we are in a tag 
        $inTag = true; 
        break 2; 
       } 
       } 
      } else { 
      $char = htmlentities($char); 
      } 
      break; 
     case '>': 
      if (!$inTag) { // No need to seek ahead here 
      $char = htmlentities($char); 
      } else { 
      $inTag = false; 
      } 
      break; 
     default: 
      if (!$inTag) { 
      $char = htmlentities($char); 
      } 
      break; 
     } 
     $xmlOut .= $char; 
    } 
    return $xmlOut; 
    } 

Đó là một máy nhà nước đơn giản ghi nhận cho dù chúng ta đang ở trong một thẻ hay không và nếu không thì hãy mã hóa văn bản bằng cách sử dụng htmlentities.

Cần lưu ý rằng đây sẽ là bộ nhớ đói trên các tệp lớn, do đó bạn có thể muốn ghi lại nó dưới dạng plugin luồng hoặc bộ xử lý trước.

+0

Tôi không thể làm việc này với MAMP trên máy Mac của mình. Nó thực sự bực bội. – Camsoft

+0

Có một thư viện PHP thuần túy tương tự như Tidy gọi là htmLawed [http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/]. Bạn có thể có nhiều may mắn hơn với điều đó. – Neel

+0

Điều này có vẻ thú vị mặc dù nó có vẻ là nhiều hơn về sửa chữa các lỗi XML. Các lỗi thực tế mà tôi đang gặp phải liên quan đến việc mã hóa hỗn hợp nội dung và các ký tự chưa được chuyển đổi thành các thực thể XML. – Camsoft

9

Để giải quyết vấn đề này, thiết lập các DomDocument recover property-TRUE trước Document tải XML

$dom->recover = TRUE;

Hãy thử mã này:

$feedURL = '3704017_14022010_050004.xml'; 
$dom = new DOMDocument(); 
$dom->recover = TRUE; 
$dom->load($feedURL); 
+0

Làm việc cho tôi, cảm ơn :) – Wiliam

+0

Làm việc với "Nội dung bổ sung ở cuối tài liệu trong Thực thể" Cảnh báo, xem http://eval.in/26395 – hakre

0

Nếu mở rộng gọn gàng không phải là một lựa chọn, bạn có thể xem xét htmlpurifier .

Các vấn đề liên quan