防止Nokogiri从URL编码src属性

时间:2014-06-11 23:06:03

标签: nokogiri libxml2

所以,似乎src属性在Nokogiri(或libxml2?)中是神圣的:

> Nokogiri::HTML.fragment('<foo src="{{bar}}"></foo>').to_html
=> "<foo src=\"%7B%7Bbar%7D%7D\"></foo>"

有没有办法避免URL编码这个属性(至少对于自定义元素)? to_xml不是一个选项(我不能保证XHTML安全的环境)。

1 个答案:

答案 0 :(得分:1)

我认为你期待Nokogiri做不应做的事情。

<foo src="{{bar}}"></foo>

不是HTML,因为<foo>不是已知的HTML标记。另一方面,它可能是一个有效的XML标记。

看看Nokogiri对你的片段做了些什么,这里用它作为HTML会发生什么:

require 'nokogiri'
doc = Nokogiri::HTML.fragment('<a src="{{bar}}"></a>')
# => #(DocumentFragment:0x3fe6d6897ba8 {
#      name = "#document-fragment",
#      children = [
#        #(Element:0x3fe6d6897900 {
#          name = "a",
#          attributes = [
#            #(Attr:0x3fe6d68978d8 { name = "src", value = "{{bar}}" })]
#          })]
#      })
doc.to_s
# => "<a src=\"%7B%7Bbar%7D%7D\"></a>"

如果将其正确地视为XML,会发生什么:

doc = Nokogiri::XML.fragment('<a src="{{bar}}"></a>')
# => #(DocumentFragment:0x3fe6d68930d0 {
#      name = "#document-fragment",
#      children = [
#        #(Element:0x3fe6d6892eb4 {
#          name = "a",
#          attributes = [
#            #(Attr:0x3fe6d6892e8c { name = "src", value = "{{bar}}" })]
#          })]
#      })
doc.to_s
# => "<a src=\"{{bar}}\"/>"
doc.to_xml
# => "<a src=\"{{bar}}\"/>"
doc.to_html
# => "<a src=\"%7B%7Bbar%7D%7D\"></a>"

Nokogiri在解析HTML时使用了一组规则,但它基本上将HTML DOM转换为内部的XML DOM,当您在将文档解析为HTML后查看文档时,可以看到它。在文档输出期间发生转换。您可以使用the parsing options轻推Nokogiri,然后输出您想要的内容。

如果您认为这是Nokogiri的不当行为,我强烈建议您在错误报告中与维护人员讨论。他们偶尔会来这里回答问题,但你会在Nokogiri谈话邮件列表或git中心页面上获得更快的回复。

如果您的标记不是有效的HTML,那么Nokogiri将尝试强制进入某种有效的HTML外观。那时你应该能够从中获得合理的XML,XHTML或HTML,其中&#34;合理的&#34;意味着它在语义上是有效的,可能并不完全符合你的期望。