关于emacs gnus对rss xml中content:encoded内容的提取

初次尝试利用gnus来订阅RSS. 然后发现生成的buffer里面没有RSS XML中content:encoded部分的内容, 所以查看了一下源代码nnrss.el, 定位之后发现问题出在这里:

(defun nnrss-check-group (group server)
   ...
   (setq content-ns (nnrss-get-namespace-prefix xml "http://purl.org/rss/1.0/modules/content/"))
   ...
   (setq extra (or (nnrss-node-text content-ns 'encoded item)
		   (nnrss-node-text rss-ns 'description item)))
)

其中 item 是解析好的xml 标签和列表, 大概这样

 (item nil (title nil "标题") (link nil "链接") (description nil "描述") (pubDate nil "日期") (guid nil "guid") (content:encoded nil "内容")

然后 nnrss-node-text会把对应标签内容提取出来, 而标签由 (concat content-ns 'encoded)生成. 问题在于这里的content-ns的值为nil, 而不是"content:", 所以就出错了. 改正这里就可以正常显示RSS的内容了.

我的问题是, 为什么这里不直接把 "content:encoded" 作为标签, 而要多此一举的用 nnrss-get-namespace-prefix 先生成 "content:", 再和encoded合并. 而且这个函数其实写错了…

附上最终的解决方案, 替换掉了错误的nnrss-get-namespace-prefix:

(defun my-nnrss-get-namespace-prefix (el uri)
  "Given EL (containing a parsed element) and URI (containing a string
that gives the URI for which you want to retrieve the namespace
prefix), return the prefix."
  (let* ((prefix (car (rassoc uri (cadar (nthcdr 2 (car el))))))
	 (nslist (if prefix
		     (split-string (symbol-name prefix) ":")))
	 (ns (cond ((eq (length nslist) 1) ; no prefix given
		    "")
		   ((eq (length nslist) 2) ; extract prefix
		    (cadr nslist)))))
    (if (and ns (not (string= ns "")))
	(concat ns ":")
      ns)))

(add-function :override (symbol-function 'nnrss-get-namespace-prefix) #'my-nnrss-get-namespace-prefix)

一般不用add-functionadvice-add

另外老哥不考虑去发补丁到emacs-devel?


add-function算是advice-add的helper

好的, 谢谢建议. 其实只改动了一点点, 可能是nnrss用的人太少了吧…

这个问题已经被上游修复了(没有测试, 我已经不用nnrss了). 我原来的修改也不对, 具体可以参见 #34685 - 26.1; function nnrss-get-namespace-prefix always returns nil - GNU bug report logs