I wrote this converter a long time ago when I was making SHOUTcast application for my PSP Radio. It was meant to transform SHOUTcast API XML response into JavaScript on the fly. I needed something simple, light and fast or the PSP wouldn’t like it. I also was discovering the awesome power of Regular Expressions at about the same time. Available solutions I found all had the same flaw – they used loops to go through XML bit by bit significantly increasing time of conversion. So I got curious if it was possible to make a one pass conversion using JavaScript “replace” function which utilises Regular Expressions. It was possible indeed.

The converter performs quick and dirty job on XML. It would probably not work with very complex XML but it is good enough for variety of simple XML. Anyway, the whole code is just one line of replace transformations:

xml = xml.replace(/\s/g, ' ').replace(/< *\?[^>]*?\? *>/g, '').replace(/< *!--[^>]*?-- *>/g, '').replace(/< *(\/?) *(\w+\b):(\w+\b)/g, '<$1$2_$3').replace(/< *(\w+\b)([^>]*?)\/ *>/g, '< $1$2>').replace(/(\w+\b):(\w+\b) *= *"([^>]*?)"/g, '$1_$2="$3"').replace(/< *(\w+\b)((?: *\w+ *= *" *[^"]*?")+ *)>( *[^< ]*?\b.*?)< *\/ *\1 *>/g, '< $1$2 value="$3">').replace(/ *(\w+\b) *= *"([^>]*?)" */g, '< $1>$2').replace(/< *(\w+\b) *< ').replace(/> *>/g, '>').replace(/< *\/ *(\w+\b) *> *< *\1 *>/g, '').replace(/"/g, '\\"').replace(/< *(\w+\b) *>([^<>]*?)< *\/ *\1 *>/g, '"$1":"$2",').replace(/< *(\w+\b) *>([^<>]*?)< *\/ *\1 *>/g, '"$1":{$2},').replace(/< *(\w+\b) *>(?=.*?< \/\1\},\{)/g, '"$1":[{').split(/\},\{/).reverse().join('},{').replace(/< *\/ *(\w+\b) *>(?=.*?"\1":\[\{)/g, '}],').split(/\},\{/).reverse().join('},{').replace(/< \/(\w+\b)\},\{\1>/g, '},{').replace(/< *(\w+\b)[^>]*?>/g, '"$1":{').replace(/< *\/ *\w+ *>/g,'},').replace(/\} *,(?= *(\}|\]))/g, '}').replace(/] *,(?= *(\}|\]))/g, ']').replace(/" *,(?= *(\}|\]))/g, '"').replace(/ *, *$/g, '');

It does look scary and I don’t really want to revisit my thought process again, but it works and it converts XML to JSON in just one pass. I also include working demo for anyone wanting to abuse it :)