created October 20, 2006 · complexity intermediate · author Cory · version 6.0
Add this to your vimrc so you can type :PrettyXML and automatically pretty-format XML. Requires the command 'xmllint' in your PATH.
Note that this ignores significant whitespace! The result will be more readable, but it may not be semantically identical. I use this to read badly-formatted XML documents, not to save them.
function! DoPrettyXML() " save the filetype so we can restore it later let l:origft = &ft set ft= " delete the xml header if it exists. This will " permit us to surround the document with fake tags " without creating invalid xml. 1s/<?xml .*?>//e " insert fake tags around the entire document. " This will permit us to pretty-format excerpts of " XML that may contain multiple top-level elements. 0put ='<PrettyXML>' $put ='</PrettyXML>' silent %!xmllint --format - " xmllint will insert an <?xml?> header. it's easy enough to delete " if you don't want it. " delete the fake tags 2d $d " restore the 'normal' indentation, which is one extra level " too deep due to the extra tags we wrapped around the document. silent %< " back to home 1 " restore the filetype exe "set ft=" . l:origft endfunction command! PrettyXML call DoPrettyXML()
I tried it on emblemsample.xml. Buffer was empty after that.
- You need xmllint in your PATH (the buffer is replaced with the output from trying to run xmllint).
The following is my solution. gvim 7.0 on Windows XP. Ruby must be installed.
# download xmlformat # copy xmlformat.rb to a folder, d:\bin for exmaple # open the xml document to be formated in Vim # type command :% !ruby d:\bin\xmlformat.rb
From Automatically indent an XML file using XSLT comes this solution, which I prefer:
:%s/></>\r</g :0 =:$
Hi, when I run this script I always get:
Error detected while processing function DoPrettyXML: line 7:
- That is because line 7 (1s/<?xml .*?>//) tried to do a substitute in line 1, and gave an error because there was no matching text in your file. I added the 'e' flag so errors will be ignored. I also did some other style tweaks. Please reply with whether it works. --JohnBeckett 01:19, 8 October 2008 (UTC)
Here is a slightly less than elegant solution to cleanup XML that is all on one line. This does not require XSLT or any special plugins, just some regular expressions.
I put this in my _vimrc
map <F5> :%s/<\([^>]\)*>/\r&\r/g<enter>:g/^$/d<enter>vat= map <F6> vatJxvito<right><left>x map <F7> /\v^\s*([a-zA-Z\-0-9\$])<enter>qm<F6>nq@q1000@@:1<enter>
When I open an XML, I hit F5... this breaks it all into individual lines. Hit F7, if you want the XML node and content to be on the same line.
When using Unicode document, xmllint converts all characters to xml entities such as � the solution is to add encoding to the xmllint line, like this:
silent %!xmllint --encode UTF-8 --format -
but there may be some more generic way (to detect the encoding and set accordingly)