如何防止<html>在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!(/<codeb[^>]*>(.*?)</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>开始和结束标签的注释,然后将生成的文本作为其内容插入到<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>

相关内容

  • 没有找到相关文章

最新更新