2008-08-15 59 views
73

我使用emacs编辑我的xml文件(nxml-mode),并且由机器生成的文件没有任何漂亮的标签格式。在Emacs上打印漂亮的XML文件

...我已经寻找漂亮的印刷与缩进整个文件并将其保存,但无法找到一个自动的方式。

有没有办法?或者至少可以做一些Linux编辑器。

回答

23

我用nXML mode编辑和Tidy时,我想格式化和缩进XML或HTML。还有an Emacs interface to Tidy.

+0

2013年底tidy.el版本:20111222.1756无法在Emacs 24上使用错误的类型参数运行:stringp,nil``` – keiw 2013-12-21 12:38:16

+0

@keiw这可能是因为你在没有文件名的缓冲区中执行它。至少有同样的错误并将其追溯到我的身边。 – Alf 2014-01-21 13:10:02

1

整洁看起来像一个很好的模式。必须看看它。如果我真的需要它提供的所有功能,请使用它。

反正这个问题我困扰了大约一个星期,我并没有正确地搜索。张贴后,我开始搜索并找到一个网站,其中有一个elisp function,这很不错。作者还建议使用Tidy。

感谢您的回答Marcel (太糟糕了,我没有足够的积分来升级你)

近期将发布关于它在我的博客。 这是一个post about it(连接到Marcel的网站)。

2
  1. Emacs nxml-mode可以使用呈现的格式,但您必须拆分这些行。
  2. 对于更长的文件,根本不值得。运行这个样式表(理想情况下与萨克森 哪些恕我直言获得行缩进约右)对较长的文件 得到一个漂亮的漂亮打印。对于要保留空白的任何元素 添加自己的名字旁边 'programlisting' 作为 'programlisting yourElementName'

HTH

85

如果你只需要在不引入任何新的换行符漂亮缩进,您可以将indent-region命令将整个缓冲区与这些按键:

C-x h 
C-M-\ 

如果您还需要引入换行符,所以打开和关闭标签是分开的,你可以使用以下非常好的elisp函数,编写Benjamin Ferrari。我在他的博客上发现了它,并希望我可以在此重现它:

(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")) 
     (indent-region begin end)) 
    (message "Ah, much better!")) 

这不依赖于外部工具,如Tidy。

+1

好的defun,谢谢。从上面的漂亮的defun中删除(nxml-mode)允许它以内置于emacs 22.2.1的sgml模式工作。但我修改它来完成整个缓冲区(point-min)到(point-max),因为那是我的主要事情。另外,还有一个错误:对于您插入的每一个换行符,您都需要增加结尾。 – Cheeso 2009-06-03 15:33:44

+0

如何在Emacs中使用此功能?我已经将函数代码复制并粘贴到* scratch *缓冲区中并进行了评估。现在,我该如何调用这个函数? – 2011-02-21 12:01:34

+1

评估defun之后,可以像调用其他任何函数一样调用它:M-x bf-pretty-print-xml-region。 (当然,你不需要输入全部,当然,使用Tab完成:Mx bf 就足够了。)你可能不想每次使用它时都定义这个函数,所以把它放在某个地方在启动时加载,例如在〜/ .emacs.d/init.el – 2011-02-22 16:50:50

93

你甚至都不需要编写自己的函数 - SGML的模式(GNU Emacs的核心模块)有一个内置的叫(SGML的漂亮打印漂亮的打印功能...)它需要区域开始和结束参数。

如果您正在剪切并粘贴xml,并且您发现您的终端正在任意位置切断线条,则可以使用此首先修复虚线的pretty printer

0

我怕我喜欢本杰明法拉利版本好多了。内部漂亮的打印总是将结束标记放在值后面的新行中,在标记值中插入不需要的CR。

33

Emacs可以使用M- |运行任意命令。如果您已经安装xmllint:

“M- | xmllint --format - ” 将格式化选定区域

“铜M- | xmllint --format - ” 会做同样的,随着替换区域输出

17

感谢Tim黑尔姆施泰特上面我做ST这样的:

(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))) 

快速和容易。非常感谢。

7

这里是我本杰明法拉利的版本做了一些调整:

  • search-forward-regexp没有指定一个结束,所以它会在东西运营从区域的开始到缓冲区(而不是区域月底结束)
  • 正如Cheeso指出的那样,现在正确地增加end
  • 它会在<tag></tag>之间插入一个中断,这会修改其值。是的,从技术上讲,我们正在修改一切的价值,但空的开始/结束更有可能是重要的。现在使用两个单独的,稍微严格的搜索来避免这种情况。

仍然有“不依靠外部整洁”,等等。但是,它确实需要clincf宏。这样做的

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;; 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!")) 
5

一种方法是 如果你有一些在下面的格式

<abc>  <abc><abc> <abc></abc> </abc></abc>  </abc> 

在Emacs,会

M-x nxml-mode 
M-x replace-regexp RET > *<RET>C-q C-j< RET 
C-M-\ to indent 

这将缩进上面的XML例子下面

<abc> 
    <abc> 
    <abc> 
     <abc> 
     </abc> 
    </abc> 
    </abc> 
</abc> 

在VI中M你可以做到这一点

:set ft=xml 
:%s/>\s*</>\r</g 
ggVG= 

希望这会有所帮助。

2

我花了Jason Viers' version并添加了逻辑来将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!")) 
1

我用xml-reformat-tagsxml-parse.el。通常,在运行此命令时,您需要在文件的开头有点。

有趣的是,该文件被合并到Emacspeak。当我每天使用Emacspeak时,我认为xml-reformat-tags是Emacs内置的。有一天,我失去了它,不得不进行互联网搜索,因此进入了上面提到的维基页面。

我也附上我的代码来启动xml解析。不知道这是否是最好的Emacs代码,但似乎适用于我。

(if (file-exists-p "~/.emacs.d/packages/xml-parse.el") 
    (let ((load-path load-path)) 
    (add-to-list 'load-path "~/.emacs.d/packages") 
    (require 'xml-parse)) 
) 
11

对于引入换行符,然后打印漂亮

M-x sgml-mode 
M-x sgml-pretty-print 
1

如果使用spacemacs,只需使用命令“spacemacs /缩进区域或缓冲”。

M-x spacemacs/indent-region-or-buffer 
0

2017年的emacs已经自带这个功能默认,但你有这个小功能写入到您的~/.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/