2

Windows 10, Emacs 25.1

Is it possible to pretty format XML file?

E.g. here not formatted xml:

<?xml version="1.0" encoding="UTF-8"?><items xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><category><category_id>2</category_id><category_title>Music</category_title></category><category><category_id>1</category_id><category_title>Entertainment</category_title></category></items>

So after format I must get the next result:

<?xml version="1.0" encoding="UTF-8"?>
<items xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <category>
      <category_id>2</category_id>
      <category_title>Music</category_title>
   </category>
   <category>
      <category_id>1</category_id>
      <category_title>Entertainment</category_title>
   </category>
</items>

Is it possible?

Drew
  • 75,699
  • 9
  • 109
  • 225
a_subscriber
  • 3,854
  • 1
  • 17
  • 47

3 Answers3

5

Try the command sgml-pretty-print from sgml-mode. This operates on the region, so you could mark the buffer first:

C-x h
M-x sgml-pretty-print

Or maybe define a command :

(defun my-xml-pretty-print ()
  (interactive)
  (unless (featurep 'sgml-mode) (require 'sgml-mode))
  (sgml-pretty-print (point-min) (point-max)))
chen bin
  • 4,781
  • 18
  • 36
glucas
  • 20,175
  • 1
  • 51
  • 83
0

Well, I have the following function for this purpose:

;;;; Pretty print XML
(defun haba/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)
    (normal-mode))
  (message "Prettified! Did my best!"))

It is not 100% bullet proof though. Very large file (very long xml line) is not always properly "prettified".

Using your example, select whole row C-x h and M-x haba/pretty-print-xml-region.

I get the result:

<?xml version="1.0" encoding="UTF-8"?>
<items xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <category>
    <category_id>2</category_id>
    <category_title>Music</category_title>
  </category>
  <category>
    <category_id>1</category_id>
    <category_title>Entertainment</category_title>
  </category>
</items>
Maxim Kim
  • 1,516
  • 9
  • 17
0

Step 1, install https://www.emacswiki.org/emacs/tidy.el and cli program tidy (On Windows, you can use Cygwin to install the program. Don't forget to add directory of program into environment variable PATH)

Step 2, insert below code into ~/.emacs

(defun tidy-xml-buffer (&optional prefix)
  "Run the Tidy program on the current XML buffer.
If PREFIX is non-nil, or if called interactively with a prefix argument,
then Tidy is applied to the currently selected region."
  (interactive "P")
  (let* ((tidy-shell-command "tidy -xml -i"))
    (tidy-buffer prefix)))

Step 3, Run M-x tidy-xml-buffer

Or maybe just run tidy -xml -i data.xml in shell without bothering Emacs.

The advantage of using tidy is performance of processing large files are great.

chen bin
  • 4,781
  • 18
  • 36