ruby - 如何替换定义节点的标签?

标签 ruby nokogiri textile

我们正在尝试从一个相当小的错误跟踪系统转移到 Redmine。对于我们的旧系统,没有现成的迁移解决方案脚本可用,所以我们想自己做。

我建议使用 Nokogiri 将一些格式移至新格式(Textile),但是,我遇到了问题。

这是来 self 们旧系统数据库中的数据库字段:

<ul>
    <li>list item 1</li>
    <li>list item 2</li>
</ul>

这需要翻译成 Textile,它看起来像这样:

* list item 1
* list item 2

现在,开始使用 Nokogiri 进行解析,我来了:

def self.handle_ul(page)
        uls = page.css("ul")
        uls.each {|ul|
                lis = ul.css("li")
                lis.each { |li|
                        li.inner_html = "*" << li.text << "\n"
                }
        }
end

这就像一个魅力。但是,我需要做两个替换:

<li>
</li>

需要从 <li> 中删除标签对象,并且:

<ul>
</ul>

需要从 <ul> 中删除标签目的。但是,我似乎无法在代表它的对象中找到实际标签。 inner_html仅返回我正在寻找的标签之间的 HTML:

ul.inner_html

结果:

<li>list item 1</li>
<li>list item 2</li>

在哪里可以找到我需要替换的标签?我考虑过使用 parent并重新关联 child <li>带有 parent.parent 的标签,但这会在祖 parent 的末尾对它们进行排序。

我能否以某种方式访问​​一个对象的整个 HTML 表示,而不去除其定义标签,以便我可以替换它们?


编辑:

根据要求,这是一个旧数据库条目的模型以及它在 textile 中应该具有的样式。

改造前:

Fixed for rev. 1.7.92.

<h4>Problems:</h4>
<ul>
<li>fixed.</li>
<li>fixed. New minimum 270x270</li>
<li>fixed.</li>
<li>fixed.</li>
<li>fixed.</li>
<li>fixed. Column types list is growing horizontally now.</li>
</ul>

改造后:

Fixed for rev. 1.7.92.

h4.Problems:
* fixed.
* fixed. New minimum 270x270
* fixed.
* fixed.
* fixed.
* fixed. Column types list is growing horizontally now.

编辑 2:

我试图覆盖 to_s 的部分内容Nokogiri 元素的方法:

li.to_s["<li>"]=""

但这似乎不是一个有效的左值(并不是说有错误,它只是什么也没做)。

最佳答案

下面是这种转换的基础:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<ul>
    <li>list item 1</li>
    <li>list item 2</li>
</ul>
EOT
puts doc.to_html

doc.search('ul').each do |ul|
  ul.search('li').each do |li|
    li.replace("* #{ li.text.strip }")
  end
  ul.replace(ul.text)
end

puts doc.to_html

运行输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><ul>
<li>list item 1</li>
    <li>list item 2</li>
</ul></body></html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>* list item 1
    * list item 2
</body></html>

我无意或尝试让第一个“项目”具有前导回车符或换行符。这留给读者作为练习。我也没有尝试处理 <h4>标签或类似的替代品。从答案代码中您应该能够弄清楚如何去做。

此外,我正在使用 Nokogiri::HTML解析 HTML,将其转换为具有适当 DOCTYPE header 的完整 HTML 文档,<html><body>标签来模拟完整的 HTML 文档。这可以使用 Nokogiri::HTML::DocumentFragment.parse 来改变。相反,但不会真正对输出产生影响。

关于ruby - 如何替换定义节点的标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16810083/

相关文章:

ruby-on-rails - 更新 gem 后出现 Rails 错误

ruby - 使用 nokogiri 提取 HTML 标签之间的文本

ruby-on-rails - 从 HTML 页面中删除所有 JavaScript

coding-style - 如何使纺织品表格行可读,例如换行或空行?

ruby-on-rails - ruby ,纺织品 : how to get plain text without tags and textile format

ruby - 确定在初始化中引用新实例的变量名称

html - 如何使用 capybara 验证记录数

Ruby 和 RVM 无法安装 ruby​​-1.9.3-p392

ruby-on-rails - Nokogiri 在服务器和本地主机上解析不同

redmine - 如何阻止Redmine自动引用问题?