23

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

29

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-\\"))
| improve this answer | |
  • 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
22

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)))
| improve this answer | |
  • 2
    In Emacs 26.1, sgml-pretty-print works directly from the nxml mode. – SergiyKolesnikov Jul 6 at 11:55
7

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/

| improve this answer | |
  • He's not asking for something to reformat it. He's asking for something to make it human readable. – RichieHH Aug 24 at 17:34
4

Mark your xml and do:

M-x sgml-pretty-print

Or just run the command without a marked region to prettify the whole buffer.

| improve this answer | |
0

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.

| improve this answer | |

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.