在 Emacs 上漂亮地打印 XML 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pretty printing XML files on Emacs
提问by cnu
I use emacs to edit my xml files (nxml-mode) and the files were generated by machine don't have any pretty formatting of the tags.
我使用 emacs 来编辑我的 xml 文件(nxml-mode),并且由机器生成的文件没有任何漂亮的标签格式。
I have searched for pretty printing the entire file with indentation and saving it, but wasn't able to find an automatic way.
我一直在寻找漂亮的缩进打印整个文件并保存它,但无法找到一种自动方式。
Is there a way? Or atleast some editor on linux which can do it.
有办法吗?或者至少有一些 linux 上的编辑器可以做到这一点。
采纳答案by Marcel Levy
I use nXML modefor editing and Tidywhen I want to format and indent XML or HTML. There is also an Emacs interface to Tidy.
当我想格式化和缩进 XML 或 HTML 时,我使用nXML 模式进行编辑和整理。Tidy还有一个 Emacs 接口。
回答by Juan Garcia
You don't even need to write your own function - sgml-mode (a gnu emacs core module) has a built-in pretty printing function called (sgml-pretty-print ...) which takes region beginning and end arguments.
您甚至不需要编写自己的函数 - sgml-mode(一个 gnu emacs 核心模块)有一个名为 (sgml-pretty-print ...) 的内置漂亮打印函数,它接受区域开始和结束参数。
If you are cutting and pasting xml and you find your terminal is chopping the lines in arbitrary places you can use this pretty printerwhich fixes broken lines first.
如果您正在剪切和粘贴 xml,并且发现您的终端在任意位置切线,您可以使用这款漂亮的打印机,它首先修复断线。
回答by Christian Berg
If you only need pretty indenting without introducing any new line-breaks, you can apply the indent-regioncommand to the entire buffer with these keystrokes:
如果您只需要漂亮的缩进而不引入任何新的换行符,您可以indent-region使用以下按键将命令应用于整个缓冲区:
C-x h
C-M-\
If you also need to introduce line-breaks, so that opening and closing tags are on separate lines, you could use the following very nice elisp function, written by Benjamin Ferrari. I found it on his blog and hope it's ok for me to reproduce it here:
如果您还需要引入换行符,以便开始和结束标签在不同的行上,您可以使用以下非常好的 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!"))
This doesn't rely on an external tool like Tidy.
这不依赖于像 Tidy 这样的外部工具。
回答by Tim Helmstedt
Emacs can run arbitrary commands with M-|. If you have xmllint installed:
Emacs 可以使用 M-| 运行任意命令。如果您安装了 xmllint:
"M-| xmllint --format -" will format the selected region
"M-| xmllint --format -" 将格式化所选区域
"C-u M-| xmllint --format -" will do the same, replacing the region with the output
"Cu M-| xmllint --format -" 会做同样的事情,用输出替换区域
回答by bubak
Thanks to Tim Helmstedt above I made st like this:
感谢上面的 Tim Helmstedt,我做了这样的 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)))
fast and easy. Many thanks.
快速简便。非常感谢。
回答by Talespin_Kit
For introducing line breaks and then pretty printing
用于引入换行符然后漂亮的打印
M-x sgml-mode
M-x sgml-pretty-print
回答by Jason Viers
here's a few tweaks I made to Benjamin Ferrari's version:
这是我对本杰明法拉利版本的一些调整:
- the
search-forward-regexpdidn't specify an end, so it would operate on stuff from beginning of region to end of buffer (instead of end of region) - Now increments
endproperly, as Cheeso noted. - it would insert a break between
<tag></tag>, which modifies its value. Yes, technically we're modifying values of everything here, but an empty start/end is much more likely to be significant. Now uses two separate, slightly more strict searches to avoid that.
- 在
search-forward-regexp没有指定一个结束,所以它会在东西从区域的开始到结束缓冲运行(而不是区域的结束) end正如 Cheeso 指出的那样,现在正确递增。- 它会在 之间插入一个中断
<tag></tag>,从而修改它的值。是的,从技术上讲,我们正在修改此处所有内容的值,但空的开始/结束更有可能是重要的。现在使用两个单独的、稍微更严格的搜索来避免这种情况。
Still has the "doesn't rely on external tidy", etc. However, it does require clfor the incfmacro.
仍然有“不依靠外部整洁”,等等。但是,它需要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!"))
回答by user1028948
One way of doing is If you have something in below format
一种方法是如果您有以下格式的内容
<abc> <abc><abc> <abc></abc> </abc></abc> </abc>
In Emacs, try
在 Emacs 中,尝试
M-x nxml-mode
M-x replace-regexp RET > *< RET >C-q C-j< RET
C-M-\ to indent
This will indent above xml example to below
这会将上面的 xml 示例缩进到下面
<abc>
<abc>
<abc>
<abc>
</abc>
</abc>
</abc>
</abc>
In VIM you can do this by
在 VIM 中,您可以通过
:set ft=xml
:%s/>\s*</>\r</g
ggVG=
Hope this helps.
希望这可以帮助。
回答by Cheeso
I took Jason Viers' versionand added logic to put xmlns declarations on their own lines. This assumes that you have xmlns= and xmlns: with no intervening whitespace.
我采用了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!"))
回答by DaveP
- Emacs nxml-mode can work on presented format, but you'll have to split the lines.
- For longer files that simply isn't worth it. Run this stylesheet (ideally with Saxon which IMHO gets the line indents about right) against longer files to get a nice pretty print. For any elements where you want to retain white space add their names alongside 'programlisting' as in 'programlisting yourElementName'
- Emacs nxml-mode 可以处理呈现的格式,但您必须拆分行。
- 对于根本不值得的更长的文件。对较长的文件运行此样式表(最好与 Saxon 一起使用,恕我直言,行缩进是正确的)以获得漂亮的打印效果。对于您想要保留空白的任何元素,在“programlisting”旁边添加它们的名称,如“programlisting yourElementName”
HTH
HTH

