TextWrangler filters to tidy XML and tidy JSON

I work with XML and JSON a lot, often as the input to or output from web services. Generally it is unformatted, so before I can read the data I need it formatted and whitespaced. So here are some TextWrangler filters to tidy up XML and JSON documents.

XMLLINT_INDENT=$'\t' xmllint --format --encode utf-8 -

Save this into a file called Tidy XML.sh

import fileinput
import json
print json.dumps( json.loads(''.join([line.strip() for line in fileinput.input()])), sort_keys=True, indent=2)

Save this into a file called Tidy JSON.py

Drop these into ~/Library/Application Support/TextWrangler/Text Filters. You can then run them on a file within TextWrangler by choosing Text > Apply Text Filter > [filter].


29 thoughts on “TextWrangler filters to tidy XML and tidy JSON

    • Thanks Dave. The guys use these at work too 🙂

      I’ve actually noticed a minor bug in the XML filter – if the XML is declared as UTF-16 but only uses UTF-8 chars, it fails to parse. The fix is to just change the UTF-16 declaration to UTF-8, however I’d love to be able to cater for that scenario.

  1. Michael says:

    I’m probably doing something stupid, but the Tidy JSON generates an error: /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py:383: ValueError: No JSON object could be decoded

    The Tidy XML works great, but I know nothing about JSON.

    • Michael says:

      Nevermind, it works on JSON examples from the web. Just not MY JSON for some reason. So there must be a missing } or , somewhere.

      • I wouldn’t recommend Eclipse for this purpose as it involves creating a new file in a specific project, just so you can paste in the content and have it reformatted to look at, then remembering to clean up/remove the file afterwards. If you do this in TextWrangler, you can do it all in an ‘untitled text’ document with a simple Command+N keystroke.

      • I concur with Steve on this one. While I do use Eclipse to do actual development. It is often more convenient to have a Text Editor like TextWrangler to read existing code, especially when it is not source controlled.

  2. Jeff says:

    The output changed order of the keys despite sort_key = true. Any clue on this? Is there a required version of Python? Thanks.

  3. It’s just a shell script. Do you want it to tidy your Java code or do you want the filter to be written in Java? If the first, you’ll need a parser that can handle that. I would probably just use Eclipse and a decent preferences imported in, to tidy it all up. If the latter, use the examples from earlier, get it running, then write a shell script wrapper for it.

    • Thank you for your prompt replies! I want it to Tidy my Java code and am interested in trying to use a Java parser. Do you have any suggestions for a Java Parser? I found this one: http://javaparser.github.io/javaparser/

      I assume I would need a shell script wrapper for the Java Parser, as well, correct?

      Do you have any resources on how to build a shell script wrapper for TextWrangler?

      • You can just call java from the command line, so using the XML example, replace the commands with the call to your class. If you use any third party libraries you’ll need them on the class path too which you can add with the -cp flag.

  4. Guy says:

    Thanks for this script!
    My only was when JSON isn’t valid, the original file is truncated (because nothing is printed) and the exception is showed as a new file in TextWrangler (which is OK). I modified it to preserve the original file:
    import fileinput
    import json
    import itertools
    input1, input2 = itertools.tee(fileinput.input())
    print json.dumps(
    json.loads(”.join(line.strip() for line in input1)),
    print ”.join(input2),

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s