【问题标题】:Xpath XML Nokogiri - LIKE expressionXpath XML Nokogiri - LIKE 表达式
【发布时间】:2013-08-13 08:59:35
【问题描述】:

我正在使用 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”。

如果有更多建议会很棒。

【问题讨论】:

  • 您可以使用fn:translate 将所有内容更改为小写音译,并丢弃除字母和数字之外的所有内容。这对于上述不同的“光环”版本来说很好,但无法处理例如“光环 IV”。
  • 感谢您的建议,我最终可能会这样做。
  • 添加了一个示例作为答案。

标签: ruby xml xpath nokogiri


【解决方案1】:

如果您能够找到所有差异,您可以尝试使用fn:translate($string, $map, $translate) 对它们进行清理。它将$map 中的每个字符替换为其在$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

【讨论】:

  • 谢谢哥们。这真的很有用。
【解决方案2】:

由于涉及到 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

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 2013-03-21
    相关资源
    最近更新 更多