【问题标题】:XML parsing in RubyRuby 中的 XML 解析
【发布时间】:2012-01-10 03:24:52
【问题描述】:

我正在使用 REXML Ruby 解析器来解析 XML 文件。但是在带有 64 位 Ruby 的 64 位 AIX 机器上,我收到以下错误:

REXML::ParseException: #<REXML::ParseException: #<RegexpError: Stack overflow in 
regexp matcher: 
/^<((?>(?:[\w:][\-\w\d.]*:)?[\w:][\-\w\d.]*))\s*((?>\s+(?:[\w:][\-\w\d.]*:)?[\w:][\-\w\d.]*\s*=\s*(["']).*?\3)*)\s*(\/)?>/mu>

类似的调用是这样的:

REXML::Document.new(File.open(actual_file_name, "r"))

有人知道如何解决这个问题吗?

【问题讨论】:

  • 这是你的正则表达式野兽还是来自 REXML?
  • 它来自 REXML。这不是我写的正则表达式。我只是使用 REXML 来解析一个 xml 文档
  • 所以,REXML 给出了“正则表达式的野兽”:D

标签: ruby-on-rails ruby xml-parsing rexml


【解决方案1】:

我有几个关于 REXML 的问题,它似乎不是最成熟的库。通常我使用Nokogiri 来解析Ruby XML,它应该比REXML 更快更稳定。使用sudo gem install nokogiri 安装后,您可以使用类似这样的方法来获取 DOM 实例:

doc = Nokogiri.XML(File.open(actual_file_name, 'rb'))
# => #<Nokogiri::XML::Document:0xf1de34 name="document" [...] >

官网上的文档也比REXML好很多,恕我直言。

【讨论】:

  • 我想知道这是否是 ruby​​ 64 位的特定问题。同样的问题在 32 位盒子上无法重现。如果有解决方法而不是安装其他库。
  • @Bharath:那么报告这个问题的更好地方是 Ruby bugtracker。
  • @Bharath:也可能是您的 XML 文件太大或嵌套太深。也许你应该尝试一些 XML 流解析器,在这种情况下。
  • 那么为什么同一个文件会被 32 位 ruby​​ 解析呢?理想情况下,64 位 ruby​​ 应该能够完成 32 位 ruby​​ 库完成的所有活动。是不是 ruby​​ 64 位有一些限制?如果是这样,是否有相同的文档?
  • @Barath:不,我宁愿认为这是一个错误。正如我所说,这并不让我感到惊讶,大多数人现在使用 Nokogiri 而不是 REXML 已经有一段时间了。
【解决方案2】:

我几乎立刻就找到了答案。

我做的第一件事是在 ruby​​ 源代码中搜索抛出的错误。 我发现 regex.h 对此负责。

在 regex.h 中,代码流程是这样的:

/* Maximum number of duplicates an interval can allow.  */
#ifndef RE_DUP_MAX
#define RE_DUP_MAX  ((1 << 15) - 1)
#endif

现在这里的问题是 RE_DUP_MAX。在 AIX 机器上,相同的常量已在 /usr/include 中的某处定义。 我搜索了一下,发现在

/usr/include/NLregexp.h
/usr/include/sys/limits.h
/usr/include/unistd.h

我不确定正在使用这三个中的哪一个(很可能是 NLregexp.h)。 在这些标头中,RE_DUP_MAX 的值已设置为 255!因此,正则表达式的重复次数有一个上限!

简而言之,原因是编译采用系统定义的值而不是我们在 regex.h 中定义的值!

这也回答了我最近提出的问题: Regex limit in ruby 64 bit aix compilation

我无法立即回答,因为我需要至少 100 名声望 :D :D 干杯!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 2014-05-16
    • 2012-10-10
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多