I have a file with xml all on one line. Does the functionality already exist to reformat this buffer to be somewhat user-readable?

up vote 16 down vote accepted

Does the functionality already exist to reformat this buffer to be somewhat user-readable?

Of course, and you have plenty of options. I'd probably feed it to an external program using:

C-x h C-u M-| xmllint --format - RET

This program comes with libxml2. You could also use tidy. Here's a list of commandline xml formatting tools: https://stackoverflow.com/questions/16090869/how-to-pretty-print-xml-from-the-command-line

You could also do a search and replace and then indent:

M-% > < RET > C-q C-j < RET ! C-M-\

Neat trick: you can copy and paste the above string into M-: (eval-expression) like this:

(execute-kbd-macro (kbd "M-% > < RET > C-q C-j < RET ! C-M-\\"))
  • A nice answer, but be wary that the command as written now will replace the buffer content with the output from the shell command. This is because of the C-u prefix. – FredrikHedman Mar 4 '17 at 14:30
  • Answer means emacs cannot do it. – Sergey Kostrukov Aug 14 at 20:31

The built-in sgml-mode has a command to do this: sgml-pretty-print. If you're in nxml-mode it looks like you need switch to sgml-mode first. You could write a command to temporarily switch to sgml-mode, run pretty-print, then switch back to nxml-mode.

For example, here is a command that will pretty-print the region, optionally with auto-fill enabled:

(defun xml-pretty-print (beg end &optional arg)
  "Reformat the region between BEG and END.
    With optional ARG, also auto-fill."
  (interactive "*r\nP")
  (let ((fill (or (bound-and-true-p auto-fill-function) -1)))
    (sgml-mode)
    (when arg (auto-fill-mode))
    (sgml-pretty-print beg end)
    (nxml-mode)
    (auto-fill-mode fill)))

write this into your ~/.emacs.d/init.el:

(require 'sgml-mode)

(defun ninrod/reformat-xml ()
  (interactive)
  (save-excursion
    (sgml-pretty-print (point-min) (point-max))
    (indent-region (point-min) (point-max))))

reload emacs, then just call M-x reformat-xml on the badly formatted xml buffer.

source: https://davidcapello.com/blog/emacs/reformat-xml-on-emacs/

Following the hint of the answer above, and assuming you have tidy installed a variation could be:

`C-x h M-| tidy -quiet -xml -utf8 -indent -`

This will open a new buffer *Shell Command Output* instead of directly replacing the contents of the buffer. After checking the result, replace the old contents with the new with:

C-x h M-insert-buffer

choose the suggested default which will probably be *Shell Command Output*. You can save the command for later with a keyboard macro:

C-x ( C-x h M-| tidy -quiet -xml -utf8 -indent - C-x)
C-x C-k n pretty-xml

With this you can execute M-x pretty-xml to reformat the buffer.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.