1

我正在使用 Nokogiri、Ruby 和 Xpath 来解析计算机游戏的大型 XML 文档。

将我试图做的事情放在上下文中......我有一个大型计算机游戏数据库,我想在 XML 文档中查找这些计算机游戏。我遇到的问题是名称可能略有不同,例如“Halo 4”、“Halo4”、“Halo: 4”

我的 XML 块如下所示:

<prod id="695980453"><pId>NH485QS</pId><text><name>Metal Gear Solid HD Collection XBox 360</name><desc>Accept the mission and play three great chapters in the Metal Gear franchise with the Metal Gear Solid HD Collection. Included are Metal Gear Solid 2: Sons of Liberty, Metal Gear Solid 3: Snake Eater and Metal Gear Solid: Peace Walker. All three games are rendered in high-definition for the first time!</desc></text><uri><awTrack>http://www.awin1.com/pclick.php?p=695980453&amp;a=161542&amp;m=3026</awTrack><awImage>http://images.productserve.com/preview/3026/695980453.jpg</awImage><mLink>http://tracking.searchmarketing.com/click.asp?aid=1719191667</mLink><mImage>http://images2.drct2u.com/content/images/products/nh/nh485/c01nh48550w.jpg</mImage></uri><price curr="GBP"><buynow>40.00</buynow><delivery>3.99</delivery></price><cat><awCatId>579</awCatId><awCat>Video Games</awCat><mCat>Main Menu|Electricals|Gaming &amp;amp; Consoles|Video Games</mCat></cat><brand><awBrandId>427</awBrandId><brandName>Xbox 360</brandName></brand></prod>

我的 xpath 目前看起来像:

game_result = file.at_xpath("//prod[text/name[text()=\"#{game.title}\"]]")

如果名称完全匹配,这可以正常工作。我尝试使用 contains 方法,但发现这会返回一些奇怪的结果......例如,任何只有单词 Halo 的东西,例如“Halo Thunder”。

任何更多的建议都会很棒。

4

2 回答 2

1

如果您能够找到所有差异,则可以尝试使用fn:translate($string, $map, $translate). $map它用 in 中的表示来替换 in 中的每个字符$translate,如果没有($translate更短)它被省略。

例如(包装在一点点 XPath 2.0 中进行演示,该fn:translate功能在 XPath 1.0 中也可用):

for $string in ('Halo 4', 'Halo: 4', 'Halo4', 'Halo-4')
return
  translate($string,
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :.-_',
    'abcdefghijklmnopqrstuvwxyz0123456789')

输出:

晕4 晕4 晕4 晕4

于 2013-08-13T12:46:23.770 回答
0

由于涉及到 Ruby,您可以使用 XPath 进行过度搜索,然后使用 Ruby 减少结果。例如:

# A magic method that returns something like /halo.+(4|iv)/i
title_regex = make_good_regex_from(game.title)
games = file.xpath("//prod").select do |prod|
  prod.at_xpath('./text/name').text =~ title_regex
end

它肯定会使用更多内存,并且可能会更慢,但它比 XPath 1.0 中可用的文本操作功能强大得多。

如果您只需要第一个匹配的产品而不是全部,请使用find而不是select.

于 2013-08-13T20:40:04.000 回答