解码HTML实体的内置方法(即“或”)


11

我最近遇到了解码html实体的问题。我有以下两个字符串(请注意如何使用两种编码方法(命名和编号))。

The old "how to fold xml" question
Babel doesn't wrap results in verbatim

我需要将它们转换为

The old "how to fold xml" question
Babel doesn't wrap results in verbatim

到处搜索,我发现了关于SO的这个老问题(这是我目前正在做的事情),但是我拒绝相信Emacs没有内置的方法。我们有几种Web浏览器,至少我知道其中两种是内置的,更不用说邮件客户端和提要阅读器了。

是否没有内置的方法来解码html实体?
我正在寻找一个函数,该函数从第一个示例获取一个字符串,然后从第二个示例返回一个字符串。


如果有的话,我敢打赌它必须在nxml代码中,因为它能够解析DTD并可以验证文档中的实体。
wasamasa 2014年

libxml-parse-html-region当然可以做到这一点,但它可能还会做更多的事情,因为它还可以解析HTML标签…(而且我猜并不是所有的Emacs都支持LibXML。)
乔恩·O。2014年

Answers:


7

Emacs在中包含一个纯Elisp XML解析器xml.el,其xml-parse-string功能可以完成这项工作,尽管看起来有点像未公开的内部功能。我不确定是否存在仅将HTML实体当作XML片段来处理的纯HTML实体。

这个包装函数将简单地省略输入字符串中的任何尾随标记,尽管您可以使其更加严格:

(defun decode-entities (html)
  (with-temp-buffer
    (save-excursion (insert html))
    (xml-parse-string)))

(decode-entities "The old "how to fold xml" question")
;; => "The old \"how to fold xml\" question"

(decode-entities "doesn't")
;; => "doesn't"

(decode-entities "string with trailing tag: <tag/>")
;; => "string with trailing tag: "

在支持LibXML的Emacs中,另一种有点怪异的方法是在周围编写包装器libxml-html-parse-region。由于LibXML解析器假定其参数是完整的HTML文档,因此包装器函数必须使用来从返回的文档结构中提取解析的字符数据pcase。尝试对包含任何HTML标签的字符串进行解码将产生错误:

(defun decode-entities/libxml (html)
  (with-temp-buffer
    (insert html)
    (let ((document
           (libxml-parse-html-region (point-min) (point-max))))
      (pcase document
        (`(html nil
                (body nil
                      (p nil
                         ,(and (pred stringp)
                               content))))
          content)
        (_ (error "Unexpected parse result: %S" document))))))

结果:

(decode-entities/libxml "The old &quot;how to fold xml&quot; question")
     ; => "The old \"how to fold xml\" question"
(decode-entities/libxml "doesn&#39;t") ; => "doesn't"

(decode-entities/libxml "<html>")              ; produces an error

通过将文档片段解析为完整文档来解码文档片段似乎确实有点落后,只是立即剥离了周围的标签。另一方面,使用LibXML应该很快并且可以给出准确的结果。


抱歉,我没有看到您的xml编辑。看起来真棒。
马拉巴巴2014年

谢谢-我编辑了答案,将简单的xml.el解决方案放在首位。
乔恩·O。

@Malabarba注意,lisp/xml.el始终包含该功能xml-substitute-special,该功能执行与Jon O.decode-entities相同的实体解码。但是,它不会省略尾随标签。
罗勒

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.