Formatting JSON and XML in Gedit

Here’s how to add commands to Gedit to format JSON and XML documents.

  1. Ensure that you have an up-to-date version of Python.  It’s included with nearly every Linux distribution.
  2. Ensure that the External Tools plugin is installed
    1. Click Edit -> Preferences
    2. Select the Plugins tab
    3. Check the box next to External Tools
    4. Click Close
  3. Add the Format JSON command
    1. Click Tools -> Manage External Tools…
    2. Click New (bottom left, looks like a piece of paper with a plus sign)
    3. Enter a name (Format JSON)
    4. Paste this text into the text window on the right
      #! /usr/bin/env python
       
      import json
      import sys
       
      j = json.load(sys.stdin)
      print json.dumps(j, sort_keys=True, indent=2)
    5. Set Input to Current document
    6. Set Output to Replace current document
  4. Add the Format XML command
    1. Install lxml (on Ubuntu, sudo apt-get install python-lxml)
      1. Python’s included XML modules either don’t support pretty printing or are buggy
    2. Create a new external tool configuration as above (Format XML)
    3. Paste this text into the text window on the right
      #! /usr/bin/env python
       
      import sys
      import lxml.etree as etree
      import traceback
       
      result = ''
      for line in sys.stdin:
        result += line
      try:
        x = etree.fromstring(result)
        result = etree.tostring(x, pretty_print=True, xml_declaration=True, encoding=”UTF-8″)
      except:
        etype, evalue, etraceback = sys.exc_info()
        traceback.print_exception(etype, evalue, etraceback, file=sys.stderr)
      print result
    4. Set Input to Current document
    5. Set Output to Replace current document

Thanks to Diego Alcorta for improvements that preserve XML declarations and set encoding!


  1. Jack says:

    A syntax error in the file “Format XML”, where the former ” quotation mark of UTF-8 should be English version.

    result = etree.tostring(x, pretty_print=True, xml_declaration=True, encoding=”UTF-8″)

  2. Phil says:

    Also, changing the settings so it doesn’t wipe out your entire file, but only what you’ve selected :

    Input: Current selection
    Oubput: Replace current selection

  3. Franco says:

    Thanks, easy and works great

  4. Alok Upadhyay says:

    Thanks! Works like a charm!

  5. Diego Alcorta says:

    It seems the comments removes the xml header, so I’m formating it

  6. Diego Alcorta says:

    To avoid removing change line:
    result = etree.tostring(x, pretty_print=True)
    to:
    result = etree.tostring(x, pretty_print=True, xml_declaration=True, encoding=”UTF-8″)

  7. Rihards says:

    Thanks,

    works great!

    R

  8. خرید کریو says:

    very nice

  9. Bart says:

    This:

    result = ”
    for line in sys.stdin:
    result += line

    can be replaced with a single line, which should hopefully be a bit more efficient too:

    result = ”.join(sys.stdin)

  10. Alex says:

    Thanks, works great!

  11. nira says:

    great tool.

    but this removes all the comments, doesn’t it?

  12. rongjie Han says:

    Hi guy it works thanks a lot

  13. Nowe says:

    Thanks! It’s awersome!

  14. hdave says:

    thanks…works. Although in Ubuntu I could see the preferences menu with invoking HUD…dunno why

  15. Doug says:

    Thanks. This quit working in my Arch install because python = python3, and the print statement causes errors now. So to fix the JSON one, just change the last line to

    print (json.dumps(j, sort_keys=True, indent=2))

    Fixing the XML was more annoying, but I just did it an easier way and changed the script to:

    #!/bin/sh
    xmllint –format –

    • Doug says:

      small XML addition:

      #!/bin/sh
      xmllint –nowarning –format –

    • Willy Loos says:

      Thanks @Doug, that works better than the python solution.
      The python2 version had trouble with non-ascii characters and i was having a hard time converting it to python3 because it wont accept xml in a string variable. Instead it wanted me to use either xmlfragment or bytearray as a data type, which meant a lot of changes to the code.

      I did have to install xmllint first, which is in the libxml2-utils package

      sudo apt-get install libxml2-utils

      cheers

  16. Sreekanth says:

    Thanks Man. This is really handy 🙂

  17. kouinkouin says:

    yeah, you saved my life with json 1 year ago. now, you save me again with xml. thanks ! 🙂

  18. Nick says:

    Worked great for me under CentOS 6.4.

    Thanks!

  19. […] Found a quick and simple way to add JSON and XML formatting to documents in gedit: http://www.connorgarvey.com/blog/?p=264. […]

  20. Oliver Dungey says:

    Sorry for the spam – tried it again with a simple xml file and it worked great. Pasted my complex xml into eclipse to check it was all valid and then formatted it without a problem. Seems it doesn’t like something in the XML but no idea what it is.

    • I’m glad you worked it out. 🙂 That’s the one downside of this method. It’s not tolerant of mistakes in the XML. The JSON formatter is worse. Since there isn’t a try/catch, it’ll print the exception back where the document was. I’ll fix that if it’s ever a problem for me again.

  21. Oliver Dungey says:

    …. Just tried dumping the python in a script and running from the command line and piping my xml file through it and still no errors or reformatting, very odd.

  22. Oliver Dungey says:

    I’m using gEdit on CentOS 6.2. I’ve managed to install all the bits and configure the commands but I tried to format my XML, nothing happened and the output all looked clean …

    “Running tool: Format XML

    Done.”

    Any ideas/suggestions?

  23. Bruno Girin says:

    This is absolutely brilliant, thanks! And I’ve learnt how to create my own gedit external tools in the process: possibilities are endless 🙂

  24. cankill says:

    Thanks a lot.

  25. Stefan says:

    It didn’t work for me, but in the Shell Output I saw

    “ImportError: No module named lxml.etree”

    so I installed “python-lxml” with

    sudo apt-get install python-lxml

    The XML won’t be formatted.

    I tried:

    Hello World

    But all it did was

    Hello World

    with two empty lines at the end

  26. Pankaj says:

    Not working for me, I did all the steps mention, open an xml file with no formatting and run the external tool,
    but not working.

    • Hi Pankaj,

      The formatter will fail if the XML is not formatted correctly. To see the error output from the formatter, make sure the bottom panel is open.

  27. Tyler says:

    This is great. Thanks.

  28. anomoomin says:

    Thanks!

Leave a Reply to Oliver Dungey