繁体   English   中英

如何防止删除 <html> 在Nokogiri中标记?

[英]How to prevent deletion of the <html> tag in Nokogiri?

我有这样的代码:

doc = Nokogiri::HTML.fragment(html)
doc.to_html

和一个将被解析的HTML片段:

<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
    <html>
        <p>
            qwerty
        </p>
    </html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>

Nokogiri删除<code>块中的<html> </html>标记。 我该如何防止这种行为?

更新:

Tin Man提出的解决方案,解析html的片段并在代码块中转义所有html

这里有一些代码,它并不漂亮所以如果你想提出另一个解决方案,请发表评论

html.gsub!(/<code\b[^>]*>(.*?)<\/code>/m) do |x|
  "<code>#{CGI.escapeHTML($1)}</code>"
end

谢谢田

问题是HTML无效。 我用它来测试它:

require 'nokogiri'

doc = Nokogiri::HTML::DocumentFragment.parse(<<EOT)
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
    <html>
        <p>
            qwerty
        </p>
    </html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT

puts doc.errors

解析文档后,Nokogiri将使用在解析过程中发现的错误列表填充errors数组。 对于HTML, doc.errors包含:

htmlParseStartTag: misplaced <html> tag

原因是,在<code>块中,标签不是HTML编码的。

使用HTML实体将其转换为:

&lt;html&gt;
    &lt;p&gt;
        qwerty
    &lt;/p&gt;
&lt;/html&gt;

它会奏效。

Nokogiri是一个XML / HTML解析器,它试图修复标记中的错误,以允许程序员很有可能使用该文档。 在这种情况下,由于<html>块位于错误的位置,因此会删除标记。 Nokogiri不关心标签是否被编码,因为在那时,它们只是文本,而不是标签。


编辑:

我将尝试使用gsub进行预解析并在代码块中转换html

require 'nokogiri'

html = <<EOT
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
    <html>
        <p>
            qwerty
        </p>
    </html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT

doc = Nokogiri::HTML::DocumentFragment.parse(html.gsub(%r[<(/?)html>], '&lt;\1html&gt;'))

puts doc.to_html

哪个输出:

<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
    &lt;html&gt;
        <p>
            qwerty
        </p>
    &lt;/html&gt;
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>

编辑:

这将在解析之前处理<html>标记,因此Nokogiri可以无损地加载<code>块。 然后它找到<code>块,对编码的<html>开始和结束标记进行unescape,然后将生成的文本作为其内容插入到<code>块中。 因为它是作为内容插入的,所以当Nokogiri将DOM呈现为HTML时,文本将在必要时重新编码为实体:

require 'cgi'
require 'nokogiri'

html = <<EOT
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
    <html>
        <p>
            qwerty
        </p>
    </html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT

doc = Nokogiri::HTML::DocumentFragment.parse(html.gsub(%r[<(/?)html>], '&lt;\1html&gt;'))

code = doc.at('code')
code.content = CGI::unescapeHTML(code.inner_html)

puts doc.to_html

哪个输出:

<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
    &lt;html&gt;
        &lt;p&gt;
            qwerty
        &lt;/p&gt;
    &lt;/html&gt;
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM