2010-08-26 56 views
3

快速版本:的XMLReader(在PHP)和錯誤處理

請告訴我標準(創新任意?)捕捉和處理由於畸形文件通過的XMLReader引發的錯誤的方式 - 特別是未轉義字符。與Tidy(等等)共存並不是一個超級吸引人的選擇,任何人都知道一種簡單地跳過違規節點並向右移動的方法?

我們都知道,這不是XML,如果沒有正確形成,但讓說實話 - 它發生:

描述版本。一個客戶經常會收集大量(50-100MB +)xml文件,這些文件需要被讀入mysql。 XMLReader是一個明顯的選擇,我們編寫了一個適合我們需求的包裝器。

偶爾會發生錯誤,並且read()會導致導入失敗 - drat!它幾乎總是一個沒有逃脫的角色(例如「&」),它將所有東西都絆倒。在大多數情況下,我們只需讓客戶致電數據提供商並要求他們修復其有缺陷的文件。不幸的是,數據提供者並不總是要求和/或及時。如果我們能夠簡單地捕捉錯誤並向下移動到下一個節點,那將會很棒。

我花了很長時間試圖閱讀/破解這一個,找不到任何值得探究的東西。我錯過了明顯的東西嗎?

This SO question似乎很有前途,但它只是沒有產生任何結果。經過1似乎應該要求讀者復甦,但我們只是沒有看到任何企圖/不同的錯誤信息,等等。下面是相關的代碼,概述了辦法:

$xml->open($file, null, LIBXML_NOERROR | LIBXML_NOWARNING | 1); 

我總是可以用預處理整潔,但必須有更好的方法。

我已經考慮了一些更具創造性的方法,比如在當前節點的邏輯完成後用try/catch嗅探下一個Read(),但看起來好像笨拙的最多。它似乎也有可能在模擬Read()中使用自定義/包裝函數來幫助遍歷節點併合並錯誤處理,但我有一種感覺是我簡化了事情。

所以總結一下:當read()失敗時,如何捕獲錯誤並移動?任何機會我們可以看到什麼錯誤即將到來(至少是XMLReader會拋出的消息)?

$xml = new XMLReader(); 
$xml->open($file); 

while ($xml->read()) { 

} 

回答

1

這是一個XML閱讀器,它是用來讀取XML的。無效的XML不是XML,不能用XML讀取器讀取 - 這很簡單。

在導入之前在文件上運行xmllint以查看其是否有效,或者執行正確的操作並告訴數據提供程序生成有效的xml。

2

關於你的問題的「看到錯誤」部分:

http://php.net/manual/en/function.libxml-use-internal-errors.php 當此設置爲默認值爲false,一個PHP的警告將得到觸發任何無效的XML。 換句話說,你應該看到它:p你只是沒有注意到,或者有一個設置或自定義錯誤處理程序有效,它隱藏了PHP警告。

如果調用真正的上述功能,不會產生任何警告,而不是錯誤將通過此函數返回內部數組中積累:

http://www.php.net/manual/en/function.libxml-get-errors.php

關於「向前走」的一部分,恐怕cweiske是正確的,它不能做到。您可以使用某些工具(即使使用XMLReader解析它們)預先篩選XML以找出錯誤,並嘗試糾正找到的錯誤,即移除/替換無效字符,但是隨後您需要重新開始解析糾正的數據。

1

我遇到了同樣的問題。使用stream filter,可以在將XML提供給XMLReader之前修復XML。

HTML to XML filter這樣做。用它作爲

$dsn = "php://filter/read=htmltoxml.entities/resource=" . $url; 
$xml = XMLReader::open($dsn);