1

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

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

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

<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<li>标签并将其与 重新关联parent.parent,但这会将它们放在祖父母的末尾。

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


编辑:

根据要求,这是一个旧 DB 条目的模型,以及它应该具有的纺织品风格。

改造前:

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_sNokogiri 元素的部分方法:

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

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

4

4 回答 4

1

您可能想查看ClothRed,它是 Ruby 中的 HTML 到 Textile 转换器。它有一段时间没有更新,但它很简单,可能是您自己的转换器的一个很好的起点。

如果您真的想使用 Nokogiri,那么您正在编写一个过滤器,因此您可能想要使用 SAX 接口。

于 2013-05-29T18:11:38.530 回答
1

这是这种转换的基础:

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 标头的完整 HTML 文档,<html>并使用<body>标签来模拟完整的 HTML 文档。可以改为使用更改,Nokogiri::HTML::DocumentFragment.parse但不会真正对输出产生影响。

于 2013-05-30T18:42:13.560 回答
1

您可能想尝试 McBean ( https://github.com/flavorjones/mcbean ) [警告:我是 gem 的作者,有一段时间没有更新]。

它在本质上类似于 ClothRed,但在底层使用 Nokogiri 并且实际上将文档结构转换为输出文本。它支持大量的 Textile 子集;事实上,正如您尝试做的那样,我已经成功地使用它在 wiki 系统之间转换 wiki 页面。

于 2013-06-02T17:26:06.593 回答
0

如果有兴趣的人稍后发现这一点,另一种选择是使用Pandoc。我刚刚进行了第一次测试,它似乎已经足够了,而且它可以做更多的格式。

于 2013-06-03T10:38:53.283 回答