2016-10-25 57 views
2

我需要使用PHP來組合不同結構化的XML文件。我正在做的是;基於條目相似度合併XML文件

  1. 使用SimpleXMLElement()
  2. 做其他文件一樣,遞增第一SimpleXMLElement()實例
  3. 保存新合併的XML文件中讀取使用simplexml_load_file()
  4. 格式化使用新結構中的元素第一個XML文件。

到目前爲止好。棘手的部分是,第一個文件有約。 3000條目,第二個文件有5000條。其中近2000條實際上是相同的;也許只是幾個字母不同而已。例如, 「聯想G50-70 CoreI5」和其他可能是「聯想G5070 I5」。

問題是,如何將第一個文件的條目與第二個文件的條目匹配;所以在新的組合文件中實際上它總共只有一個條目?

我使用PHP和SmithWatermanGotoh的similar_text()函數來計算相似度,它與86%的分數成比例;這對我來說已經足夠了。但是迭代另一個文件的所有條目以僅匹配一個條目對我來說是非常不明智和耗費資源的。 Beucase意思是約。每次我保存一個新的更新文件時,7MB的文件加載到內存中至少執行15.000次迭代。

我認爲將所有條目插入到數據庫表中並使用Sphinx Search來匹配條目;但我不確定它是否真的有足夠的幫助。

+1

如果內存問題,[發電機](http://php.net/manual/ro/language.generators.overview.php)可能會有所幫助。 – Andrew

+1

我認爲這裏的主要問題是'similar_text()'的複雜性。如果我是你,我將定義一組規則以獨特的方式格式化每個條目,然後你可以很容易地找到重複。 –

+1

@CasimiretHippolyte,我無法清楚地練習你的建議,你會更具體嗎?順便說一句,有完全相同的條目,又名重複;但也有同樣的條目,但不完全重複。就像問題中給出的例子一樣。 – Turab

回答

1

我可以看到的最好方法是使用array_uintersect()函數的自定義回調函數。這種方式的步驟像是;

1-編寫一個計算相似度的比較函數。從php.net檢查array_uintersect()手冊,以瞭解如何編寫此回調函數。說它的名字將是find_similar_entries()

2-將兩個條目從不同的XML文件分別收集到兩個數組中。 (對於快速方法,先執行json_encode(),然後再執行json_decode()。)

3-具有相交功能找到類似的條目; $similar_products = array_uintersect($xml_array1, $xml_array2, 'find_similar_entries');

4-現在你在一個數組中收集了類似的條目。請致電array_diff()刪除原始數組中的類似條目。

6-最後,根據您的願望,使用SimpleXMLElement()類將所有三個數組組合爲一個新的XML結構。注1:我用similar_text()和SmithWatermanGotoh來計算相似度,他們可以很好地協同工作,我可以說。但是當涉及非常接近的產品名稱可能相差幾個字符時,它們最終會變成「相同的」。除了從字符串中提取區分詞外,沒有什麼可以做的。就像我的例子中的「型號名稱」一樣。注意2:此方法按預期工作,但PHP的交集函數有一個我認爲的錯誤,這使得這些函數非常慢。我爲此創建了a bug report。交叉點不僅僅交叉比較兩個數組的元素;但它也會比較陣列自己的元素。這實際上是不合邏輯的,因爲相交只能通過比較至少兩方來計算。所以比較內部的一個數組實際上並不是「交集」。這就是爲什麼如果你有大文件,如果你直接運行這個文件,你的腳本就會死掉。也許你可以通過大塊來完成它。