我使用emacs编辑我的xml文件(nxml-mode),由机器生成的文件没有任何标记的漂亮格式。
我搜索了整个文件的漂亮打印和缩进保存的方法,但没有找到自动的方法。
有没有办法?或者至少在Linux上有一些可以做到的编辑器。
你甚至不需要编写自己的函数 - sgml-mode (gnu emacs 的一个核心模块) 内置了一个称为 (sgml-pretty-print ...) 的漂亮打印函数,它接受区域开始和结束参数。
如果你在剪切和粘贴 xml 时发现终端会在任意位置截断行,你可以使用这个漂亮打印工具先修复破损的行。
如果你只需要漂亮的缩进而不引入任何新的换行符,你可以使用这些按键将indent-region
命令应用于整个缓冲区:
C-x h
C-M-\
(defun bf-pretty-print-xml-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
(goto-char begin)
(while (search-forward-regexp "\>[ \\t]*\<" nil t)
(backward-char) (insert "\n") (setq end (1+ end)))
(indent-region begin end))
(message "Ah, much better!"))
(insert "\n")
,您还需要将 end
增加 1,以便缩进整个区域,否则可能会错过最后几行。此更正已添加到本答案中提供的 Benjamin Ferrari 博客链接中。 - Kind StrangerEmacs 可以通过 M-| 运行任意命令。如果您已经安装了 xmllint:
"M-| xmllint --format -" 将格式化所选区域
"C-u M-| xmllint --format -" 将执行同样的操作,但替换所选区域为输出结果
我使用nXML模式进行编辑,Tidy用于格式化和缩进XML或HTML。还有一个Emacs界面到Tidy。
wrong type argument: stringp, nil
。 - keiw用于插入换行符并进行格式化打印
M-x sgml-mode
M-x sgml-pretty-print
多亏了上面的Tim Helmstedt,我做出了以下的样式:
(defun nxml-pretty-format ()
(interactive)
(save-excursion
(shell-command-on-region (point-min) (point-max) "xmllint --format -" (buffer-name) t)
(nxml-mode)
(indent-region begin end)))
(indent-region 0 (count-lines (point-min) (point-max)))
。 - John J. Camilleri这是我对Benjamin Ferrari版本进行的一些调整:
search-forward-regexp
没有指定结束位置,因此它会在区域开头到缓冲区结尾(而不是区域结尾)操作。end
的值,正如Cheeso所指出的那样。<tag></tag>
之间插入一个断点,从而修改其值。是的,技术上我们在这里修改了所有内容的值,但空的开始/结束更有可能是重要的。现在使用两个单独的、稍微更严格的搜索来避免这种情况。仍然具有“不依赖外部整洁”等特点。但是,它需要cl
来支持incf
宏。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pretty print xml region
(defun pretty-print-xml-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
(goto-char begin)
;; split <foo><foo> or </foo><foo>, but not <foo></foo>
(while (search-forward-regexp ">[ \t]*<[^/]" end t)
(backward-char 2) (insert "\n") (incf end))
;; split <foo/></foo> and </foo></foo>
(goto-char begin)
(while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t)
(backward-char) (insert "\n") (incf end))
(indent-region begin end nil)
(normal-mode))
(message "All indented!"))
一种做法是,如果你有以下格式的东西
<abc> <abc><abc> <abc></abc> </abc></abc> </abc>
M-x nxml-mode
M-x replace-regexp RET > *< RET >C-q C-j< RET
C-M-\ to indent
<abc>
<abc>
<abc>
<abc>
</abc>
</abc>
</abc>
</abc>
:set ft=xml
:%s/>\s*</>\r</g
ggVG=
~/.emacs.d/init.el
文件中:(require 'sgml-mode)
(defun reformat-xml ()
(interactive)
(save-excursion
(sgml-pretty-print (point-min) (point-max))
(indent-region (point-min) (point-max))))
然后只需调用M-x reformat-xml
来源:https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/
我采用了Jason Viers的版本,并添加了逻辑来将xmlns声明放在自己的行上。这假设你有xmlns=和xmlns:之间没有空格。
(defun cheeso-pretty-print-xml-region (begin end)
"Pretty format XML markup in region. You need to have nxml-mode
http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
this. The function inserts linebreaks to separate tags that have
nothing but whitespace between them. It then indents the markup
by using nxml's indentation rules."
(interactive "r")
(save-excursion
(nxml-mode)
;; split <foo><bar> or </foo><bar>, but not <foo></foo>
(goto-char begin)
(while (search-forward-regexp ">[ \t]*<[^/]" end t)
(backward-char 2) (insert "\n") (incf end))
;; split <foo/></foo> and </foo></foo>
(goto-char begin)
(while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t)
(backward-char) (insert "\n") (incf end))
;; put xml namespace decls on newline
(goto-char begin)
(while (search-forward-regexp "\\(<\\([a-zA-Z][-:A-Za-z0-9]*\\)\\|['\"]\\) \\(xmlns[=:]\\)" end t)
(goto-char (match-end 0))
(backward-char 6) (insert "\n") (incf end))
(indent-region begin end nil)
(normal-mode))
(message "All indented!"))
sgml-mode
随着时间的推移可能会有哪些变化。今天,我通过执行C-x C-f foo.xml
、M-x sgml-mode
和M-x sgml-pretty-print
,对我的XML文件进行了漂亮的打印。在漂亮的打印之前,它是一个单行文件,在漂亮的打印之后则有720行。(不过,在完成之前,Emacs挂起了二十秒或更长时间。) - daveloyallC-x g
命令以选择整个缓冲区作为一个区域。 - daveloyallC-x h
然后M-x sgml-pretty-print
。现在 XML 将被漂亮地格式化。 - Swedgin