在HTML文件的样式字段中更改URI

时间:2014-09-08 14:27:00

标签: ruby nokogiri

我有一个HTML文件:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">

  td[id="module1header"] {
        width: 310px !important;
        height: 75px !important;
        margin-top: 25px;
        text-align: center !important;
        font-size: 21px !important;
        vertical-align: bottom !important;
    }
    td[class="module1"] {
        text-align:center;
        padding:0 0 0 20px !important;
        width:335px;
    }
    span[id="modulediv1"] {
        width: 370px !important;
        height: 379px !important;
        background-image: url(http://www.url.com/somefile.jpg) !important;
    }
</style>
<html>
<head>

使用Nokogiri我想访问<style type="text/css"> </style>内的每个URI并进行更改。 我正在尝试这样的事情:

htext= File.open(inputOpts.html_file).read
h_docc = Nokogiri::HTML(htext)
h_doc.css('td[style]').each do |style|
//modify uri hear.
end

但该代码无法访问该样式。如何访问样式字段中的每个URI然后更改它?

2 个答案:

答案 0 :(得分:1)

h_doc.css('td[style]')是一种CSS匹配方法,在这种情况下,tdstyle HTML属性匹配:

>> Nokogiri::HTML('<style></style><td style></td>').css('td[style]').to_s
#=> "<td style></td>"

为了匹配style代码,您必须使用style代码选择器:

>> Nokogiri::HTML('<style></style><td style></td>').css('style').to_s
#=> "<style></style>\n"

答案 1 :(得分:0)

您正在尝试使用解析HTML的Nokogiri来解析CSS。你无法从这里到达那里。

相反,你可以使用Nokogiri找到合适的CSS块,然后使用常规的String munging工具对其进行操作:

require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">

  td[id="module1header"] {
        width: 310px !important;
        height: 75px !important;
        margin-top: 25px;
        text-align: center !important;
        font-size: 21px !important;
        vertical-align: bottom !important;
    }
    td[class="module1"] {
        text-align:center;
        padding:0 0 0 20px !important;
        width:335px;
    }
    span[id="modulediv1"] {
        width: 370px !important;
        height: 379px !important;
        background-image: url(http://www.url.com/somefile.jpg) !important;
    }
</style>
<html>
<head>
EOT

此时doc是一个解析并准备好被操作的DOM:

new_url = 'http://www.example.com/index.html'

doc.search('style').each do |style|
  style.content = style.content.sub(/\burl\([^)]+\)/, "url(#{ new_url })")
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>
# >> <head>
# >> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
# >> <style type="text/css">
# >> 
# >>   td[id="module1header"] {
# >>         width: 310px !important;
# >>         height: 75px !important;
# >>         margin-top: 25px;
# >>         text-align: center !important;
# >>         font-size: 21px !important;
# >>         vertical-align: bottom !important;
# >>     }
# >>     td[class="module1"] {
# >>         text-align:center;
# >>         padding:0 0 0 20px !important;
# >>         width:335px;
# >>     }
# >>     span[id="modulediv1"] {
# >>         width: 370px !important;
# >>         height: 379px !important;
# >>         background-image: url(http://www.example.com/index.html) !important;
# >>     }
# >> </style>
# >> 
# >> 
# >> </head>
# >> </html>

请注意,嵌入的URL现已更新。

doc.search('style')会返回文档中找到的所有<style>代码。如果您需要特定的一个,则需要将'style'修改为更合适的CSS或XPath选择器,或找出确定是否继续使用该特定标记的方法。

style.content返回标记的内容。这不一定是标签的文字; <style>标记内的CSS样式表是按文件定义的文本。 style.content =是我们将内容分配给特定代码的方式,以便代码获取现有的CSS样式信息,对其执行sub,并将其重新分配给代码作为代码的内容。

/\burl\([^)]+\)/是一个正则表达式,用于查找url自立; \b是一个单词边界。 \([^)]+\)表示&#34;找到一个左括号,其中的所有文本直到下一个右括号,以及该右括号。&#34;这有助于我们隔离要替换的文本块。其余的应该很容易理解。