【问题标题】:Ruby Nokogiri - How to prevent Nokogiri from printing HTML character entitiesRuby Nokogiri - 如何防止 Nokogiri 打印 HTML 字符实体
【发布时间】:2016-03-04 01:30:35
【问题描述】:

我有一个 html,我正在使用 Nokogiri 解析它,然后像这样生成一个 html

htext= File.open(input.html).read
h_doc = Nokogiri::HTML(htmltext)
/////Modifying h_doc//////////

File.open(output.html, 'w+')  do |file|
file.write(h_doc)
end

问题是如何防止NOkogiri在最终生成的html文件中打印HTML字符实体(< >, &  )

我想打印实际字符( 等),而不是 HTML 字符实体 (< > &  )

As an example it is printing the html like
 <title>&lt;%= ("/emailclient=sometext") %&gt;</title>
and I want it to output like this
<title><%= ("/emailclient=sometext")%></title>

【问题讨论】:

    标签: ruby nokogiri


    【解决方案1】:

    所以...您希望 Nokogiri 输出不正确或无效的 XML/HTML?

    我有最好的建议,事先用其他东西替换这些序列,用 Nokogiri 将其剪切,然后将它们替换回来。您的输入不是 XML/HTML,没有必要期望 Nokogiri 知道如何正确处理它。因为看:

    <div>To write "&amp;", you need to write "&amp;amp;".</div>
    

    这呈现:

    To write "&", you need to write "&amp;".
    

    如果你有自己的方式,你会得到这个 HTML:

    <div>To write "&", you need to write "&amp;".</div>
    

    将呈现为:

    To write "&", you need to write "&".
    

    在这种情况下甚至更糟,比如在 XHTML 中:

    <div>Use the &lt;script&gt; tag for JavaScript</div>
    

    如果你替换实体,你会得到无法显示的文件,因为 &lt;script&gt; 标签未关闭:

    <div>Use the <script> tag for JavaScript</div>
    

    编辑我仍然认为你试图让 Nokogiri 做一些它不打算做的事情:处理模板 HTML。我宁愿假设您的文档通常不包含这些序列,然后对它们进行更正:

    doc.traverse do |node|
      if node.text?
        node.content = node.content.gsub(/^(\s*)(\S.+?)(\s*)$/,
                                         "\\1<%= \\2 %>\\3")
      end
    end
    puts doc.to_html.gsub('&lt;%=', '<%=').gsub('%&gt;', '%>')
    

    【讨论】:

    • 我认为必须有某种方法可以做到这一点。原始的html是 sometext 的形式,我希望它像这样替换 。但我越来越喜欢这个 &lt%;sometext%> 。我真的觉得一定有什么办法。
    • stackoverflow.com/questions/4476047/… 。这个链接谈论做我想做的相反的事情。
    • 只是为了添加更多信息,我正在更改 html 变量文本,如下所示 h_doc.traverse do |x|如果 x.text? x.content ="" end end end
    【解决方案2】:

    你绝对可以阻止 Nokogiri 改变你的实体。它甚至是一个内置功能,不需要伏都教或黑客攻击。请注意,我不是 nokogiri 大师,只有当我直接在文档内的节点上执行时才能使用它,但我敢肯定,稍微挖掘一下就可以向您展示如何使用独立节点执行此操作也是。

    当您创建或加载文档时,您需要包含 NOENT 选项。而已。大功告成,您现在可以将实体添加到您的心脏内容中。

    需要注意的是,大约有六种方法可以调用带有选项的文档,以下是我个人最喜欢的方法。

       require 'nokogiri'
       noko_doc = File.open('<my/doc/path>') { |f| Nokogiri.<XML_or_HTML>(f, &:noent)}
       xpath = '<selector_for_element>'
       noko_doc.at_<css_or_xpath>(xpath).set_attribute('I_can_now_safely_add_preformatted_entities!', '&amp;&amp;&amp;&amp;&amp;')
       puts noko_doc.at_xpath(xpath).attributes['I_can_now_safely_add_preformatted_entities!']
    >>> &amp;&amp;&amp;&amp;&amp;
    

    至于这个功能的用处……我觉得它非常有用。在很多情况下,您正在处理您无法控制的预格式化数据,并且必须管理传入的实体以便 nokogiri 可以将它们恢复到原来的样子,这将是一个严重的痛苦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-14
      • 2010-12-26
      • 2011-01-29
      • 2010-12-17
      • 2013-05-02
      • 2023-03-22
      • 2012-09-21
      • 1970-01-01
      相关资源
      最近更新 更多