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


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 '18 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)))
    (when arg (auto-fill-mode))
    (sgml-pretty-print beg end)
    (auto-fill-mode fill)))

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

(require 'sgml-mode)

(defun ninrod/reformat-xml ()
    (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.


You can leverage the tidy command line program to do the dirty work for you. See the tidy man page for options that are sent below in 'call-process-region'. With an xml file/buffer open, execute M-x tidy-xml-buffer to format/indent the buffer's xml. '-xml' means require valid xml. '-i' means indent the xml. '-wrap 0' means don't wrap text. '-omit' means eliminate any unnecessary closing tags. '-q' means quiet output.

(defun tidy-xml-buffer ()
          (call-process-region (point-min) (point-max) "tidy" t t nil
                               "-xml" "-i" "-wrap" "0" "-omit" "-q" "-utf8")))

      (bind-key "C-c M-h" #'tidy-xml-buffer nxml-mode-map)

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

  • Can you elaborate? Some context besides code would be nice. – DoMiNeLa10 yesterday

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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