Pretty printing XML files on Emacs
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.
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.
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.
If you are cutting and pasting xml and you find your terminal is chopping the lines in arbitrary places you can use this pretty printer which fixes broken lines first.
If you only need pretty indenting without introducing any new line-breaks, you can apply the indent-region
command to the entire buffer with these keystrokes:
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:
(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!"))
This doesn't rely on an external tool like Tidy.
Emacs can run arbitrary commands with M-|. If you have xmllint installed:
"M-| xmllint --format -" will format the selected region
"C-u M-| xmllint --format -" will do the same, replacing the region with the output
I use nXML mode for editing and Tidy when I want to format and indent XML or HTML. There is also an Emacs interface to Tidy.
Thanks to Tim Helmstedt above I made st like this:
(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.