sponsor Vim development Vim logo Vim Book Ad

basic Tip #349: Format your xml document using xmllint

 tip karma   Rating 115/52, Viewed by 9842 

Read and edit this tip on the Vim tip wiki. The wiki may have a more recent version of this tip.

created:   October 23, 2002 17:18      complexity:   basic
author:   Daniel Allen      as of Vim:   6.0

If you open an xml document that is either totally or partially unindented, you can use the GNU libxml2 libary's xmllint to reformat and align your document.  This is especially good if you want to save your xml documents using as little space as possible (which would be totally unindented).  Just add this under the autocmd section of your .vimrc file

au FileType xml exe ":silent 1,$!xmllint --format --recover - 2>/dev/null"

This instructs vim to take the entire contents of a *.xml file and pass it through xmllint, using the --format and --recover flags and silencing any errors that may occur.  This is generally a very effective process and will only mess up on very poorly typed (a large amout of incorrect syntax) xml documents.  Please note that xmllint only adds and removes structural space.  It does not remove space from regular text nodes (as doing so would be incorrect).

 rate this tip  Life Changing Helpful Unfulfilling 

<< Quickly insert a single word | when 'formatoptions' has o easily enter a non commented line: go/gO mappings >>

Additional Notes

Anonymous, October 24, 2002 14:11
will this work in win2k version of gvim?
[email protected], October 29, 2002 16:59
How can make it as a filter?

I tried sth like
  let&l;:equalprg='xmllint --format --recover'

but it didn't work since xmllint doesn't take STDIN?

any idea?
dean at mndsolutions dot de, November 8, 2002 9:47
notice the '-' given as the file argument to xmllint. This usually means stdin.
[email protected], November 14, 2002 13:13
Yes, xmllint can read from stdin, please note the '-' that occurs at the end of the options.  This tells it to dump the file contents to the stdin pipe for xmllint.  As far as I know, xmllint can be run in windows if you have gcc, but I am just projecting...look into it.  If not, I am sure you can find something to take its place...the tip is just that, a tip, build on it.
tobiasreif pinkjuice com, December 20, 2002 12:39
Regarding the filter question:

Start playing with

" one or more lines:
vmap ,px !xmllint --format -<CR>

" pretty-print current line
nmap ,px !!xmllint --format -<CR>

Question:
How to send s.th. like }?
(as with >})
... so that no visial selection is necessary.

Tobi
[email protected], January 11, 2003 11:55
"xmllint --format" indents comment lines to 0 which screws up the formatting for vim.  A simple fix for single line comments can be made in indent/xml.vim.  Copy indent/xml.vim to ~/.vim/xml.vim (Unix systems) and change the line that says:

let lnum = prevnonblank(a:lnum - 1)

To this:

   let lnum = a:lnum
    while lnum > 0
        let lnum = prevnonblank(lnum - 1)
        let line = getline(lnum)
        if strpart(line, 0, 4) != "<!--"
            break
        endif
    endwhile

Gary Godfrey
Austin, TX USA
[email protected], January 14, 2003 12:12
Nobody answered the previous question, as I am also curious, how does one make this work in the win32 version of vim?
Anonymous, January 21, 2003 11:30
This might be helpful to you in making xmllint work with gvim under Windows,

http://www.pinkjuice.com/vim/vimrc.txt
Klaus Horsten, June 14, 2003 11:05
Windows:
GNU libxml2 libary's xmllint.exe is buggy.

(See http://gnuwin32.sourceforge.net/packages.html)

Nothing happens. The input is the same as the output.

It does not work on windows, because the xmllint.exe is unusable (at least in this respect).

This is true for June 2003.

The syntax in vim would be easy:

Go into the xml-file and type:
:! xmllint.exe --format %

--Klaus
[email protected], July 21, 2003 15:18

Klaus Horsten wrote:
> It does not work on windows, because the xmllint.exe
> is unusable (at least in this respect)."

Try
http://www.zlatkovic.com/projects/libxml/
http://www.zlatkovic.com/projects/libxml/binaries.html .

Currently the latest version is
http://www.zlatkovic.com/projects/libxml/libxml2-2.5.8.win32.zip .

> The syntax in vim would be easy:
>
> Go into the xml-file and type:
> :! xmllint.exe --format %

This would do nothing by itself AFAICS.

Check
http://www.pinkjuice.com/howto/vimxml/setup.xml#xmllint ,
http://www.pinkjuice.com/howto/vimxml/tasks.xml#prettyprinting and
http://www.pinkjuice.com/howto/vimxml/tasks.xml#validation

Tobi


[email protected], August 4, 2003 14:35
One problem with "xmllint --format" is that it turns non-ASCII UTF-8 characters into numeric references. This isn't a problem if you're taking the input of xmllint and editing it with an XML editor that internally converts everything to UTF-8 (like XMetal), but if what you want to do is use Vim to edit the file as a native UTF-8 (with :set encoding=utf8), then you *don't* want a bunch of numeric references instead of Unicode.

The xmllint developer knows about this issue but feels that adding an option to keep/not keep UTF-8 would complicate the code too much. So... is there another XML reformatter more suitable for producing output that Vim can use?
tobiasreif pinkjuice com, August 21, 2003 14:30
Hi,

try
http://www.pinkjuice.com/howto/vimxml/tasks.xml#prettyprinting

HTH,
Tobi
tobiasreif pinkjuice com, August 24, 2003 7:37

I will change the solution described at the above URL since there is a very simple solution to the problem:

http://mail.gnome.org/archives/xml/2003-August/msg00017.html
http://mail.gnome.org/archives/xml/2003-August/msg00018.html

:%!xmllint --format --encode UTF-8 -

Tobi

[email protected], September 16, 2003 7:57
Any ideas on how to use xmllint, but change the tab/indent width? It seems to filter, on windows, with 2 spaces for a tab.
Anonymous, June 30, 2004 3:32
Some of my documents are cut in half when I use xmllint with -. There is most likely some limit for stdin. Is it possible to use it in another way?
I'm on MS Windows with Vim 6.3...

[email protected], August 14, 2004 7:27
I was dissatisfied with what xmllint was doing to my XML documents. Its --format option seems to arbitrarily expand or remove blank lines.

An alternative is to use the tidy program - formerly HTML Tidy. available at http://tidy.sourceforge.net/ I altered my .vimrc as follows:

au FileType xml exe ":silent 1,$!tidy --input-xml true --indent yes 2>/dev/null"

Much nicer. :)
[email protected], August 26, 2006 13:04
Here's how you use tidy with xml on Windows:

    au FileType xml exe ":silent 1,$!tidy -q -i -xml"
code __at__ sujee _*dot*_ net, November 17, 2006 11:44
I have this in my .vimrc

"-----
" select xml text to format and hit ,x
vmap ,x :!tidy -q -i -xml<CR>
"---
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
   
SourceForge.net Logo