2016-10-25 26 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。交叉点不仅仅交叉比较两个数组的元素;但它也会比较阵列自己的元素。这实际上是不合逻辑的,因为相交只能通过比较至少两方来计算。所以比较内部的一个数组实际上并不是“交集”。这就是为什么如果你有大文件,如果你直接运行这个文件,你的脚本就会死掉。也许你可以通过大块来完成它。