我花了两个小时谷歌搜索这个,我找不到任何好的答案,所以让我们看看人类是否可以击败谷歌电脑。
我想在Ruby中解析样式表,以便我可以将这些样式应用于我的文档中的元素(以使样式内联)。所以,我想采取像
这样的东西<style>
.mystyle {
color:white;
}
</style>
并能够将其提取到某种Nokogiri对象中。
Nokogiri类“CSS :: Parser”(http://nokogiri.rubyforge.org/nokogiri/Nokogiri/CSS/Parser.html)肯定有一个很有希望的名字,但我找不到任何关于它是什么或它是如何工作的文档,所以我不知道它是否可以做我在这里的事。
我的最终目标是能够编写如下代码:
a_web_page = Nokogiri::HTML(html_page_as_string)
parsed_styles = Nokogiri::CSS.parse(html_page_as_string)
parsed_styles.each do |style|
existing_inlined_style = a_web_page.css(style.declaration) || ''
a_web_page.css(style.declaration)['css'] = existing_inlined_style + style.definition
end
哪个会从样式表中提取样式,并将它们全部作为内联样式添加到我的文档中。
答案 0 :(得分:15)
Nokogiri无法解析CSS样式表。
您遇到的CSS::Parser
解析CSS 表达式。只要您通过CSS选择器遍历HTML树而不是XPath(这是Nokogiri的cool feature),就会使用它。
但是有一个Ruby CSS parser。你可以和Nokogiri一起使用它来达到你想要的效果。
require "nokogiri"
require "css_parser"
html = Nokogiri::HTML(html_string)
css = CssParser::Parser.new
css.add_block!(css_string)
css.each_selector do |selector, declarations, specificity|
element = html.css(selector)
element["style"] = [element["style"], declarations].compact.join(" ")
end
答案 1 :(得分:3)
@molf肯定有一个很好的开始,但它仍然需要调试一些问题才能让它在生产中运行。以下是目前经过测试的版本:
html = Nokogiri::HTML(html_string)
css = CssParser::Parser.new
css.add_block!(html_string) # Warning: This line modifies the string passed into it. In potentially bad ways. Make sure the string has been duped and stored elsewhere before passing this.
css.each_selector do |selector, declarations, specificity|
next unless selector =~ /^[\d\w\s\#\.\-]*$/ # Some of the selectors given by css_parser aren't actually selectors.
begin
elements = html.css(selector)
elements.each do |match|
match["style"] = [match["style"], declarations].compact.join(" ")
end
rescue
logger.info("Couldn't parse selector '#{selector}'")
end
end
html_with_inline_styles = html.to_s