Vim Tips Wiki
No edit summary
(`%` (1 char) is easier to type and more comprehensible than `1,$` (3 chars).)
(13 intermediate revisions by 9 users not shown)
Line 1: Line 1:
  +
{{TipImported
{{Tip
 
 
|id=349
 
|id=349
  +
|previous=348
|title=Format your xml document using xmllint
 
  +
|next=350
|created=October 23, 2002 17:18
+
|created=2002
 
|complexity=basic
 
|complexity=basic
 
|author=Daniel Allen
 
|author=Daniel Allen
 
|version=6.0
 
|version=6.0
 
|rating=96/42
 
|rating=96/42
  +
|category1=Syntax
|text=
 
  +
|category2=XML
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).
 
 
}}
 
}}
 
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]]:
  +
<pre>
 
au FileType xml exe ":silent %!xmllint --format --recover - 2>/dev/null"
  +
</pre>
   
 
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 amount 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).
== Comments ==
 
will this work in win2k version of gvim?
 
   
 
==Comments==
   
  +
===xmllint as a filter===
'''Anonymous'''
 
 
'''Q:''' How can make it as a filter?
, October 24, 2002 14:11
 
----
 
How can make it as a filter?
 
   
I tried sth like
+
I tried sth like
let&amp;l:equalprg='xmllint --format --recover'
+
let&l:equalprg='xmllint --format --recover'
   
but it didn't work since xmllint doesn't take STDIN?
+
but it didn't work since xmllint doesn't take STDIN?
   
 
'''A:''' Notice the '-' given as the file argument to xmllint. This usually means stdin. So, the full command should be:
any idea?
 
   
 
let &l:equalprg='xmllint --format --recover -'
maxiangjiang--AT--homail.com
 
, October 29, 2002 16:59
 
----
 
notice the '-' given as the file argument to xmllint. This usually means stdin.
 
 
dean at mndsolutions dot de
 
, November 8, 2002 9:47
 
----
 
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.
 
 
dan--AT--mojavelinux.com
 
, November 14, 2002 13:13
 
----
 
Regarding the filter question:
 
 
Start playing with
 
 
" one or more lines:
 
vmap ,px !xmllint --format -&lt;CR&gt;
 
   
 
'''A:''' 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.
" pretty-print current line
 
nmap ,px !!xmllint --format -&lt;CR&gt;
 
   
 
'''A:''' Regarding the filter question:
Question:
 
How to send s.th. like }?
 
(as with &gt;})
 
... so that no visial selection is necessary.
 
   
 
Start playing with
Tobi
 
   
 
" one or more lines:
 
vmap ,px !xmllint --format -<CR>
 
" pretty-print current line
 
nmap ,px !!xmllint --format -<CR>
   
tobiasreif pinkjuice com
 
, December 20, 2002 12:39
 
 
----
 
----
"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:
 
   
  +
===Fixing indenting of comment lines===
let lnum = prevnonblank(a:lnum - 1)
 
   
 
"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:
To this:
 
   
let lnum = a:lnum
+
let lnum = prevnonblank(a:lnum - 1)
while lnum &gt; 0
 
let lnum = prevnonblank(lnum - 1)
 
let line = getline(lnum)
 
if strpart(line, 0, 4) != "&lt;!--"
 
break
 
endif
 
endwhile
 
   
 
To this:
Gary Godfrey
 
Austin, TX USA
 
   
  +
<pre>
 
let lnum = a:lnum
 
while lnum > 0
 
let lnum = prevnonblank(lnum - 1)
 
let line = getline(lnum)
  +
if line =~ '-->'
  +
let [lnum,watever] = searchpos('<!--','b')
  +
else
  +
break
  +
endif
 
endwhile
  +
</pre>
   
  +
Alone-on-line end-of-comment closing-tags may get badly indented though.
ggodfrey--AT--io.com
 
, January 11, 2003 11:55
 
 
----
 
----
Nobody answered the previous question, as I am also curious, how does one make this work in the win32 version of vim?
 
   
  +
===xmllint on Windows===
johngraves03--AT--comcast.net
 
, January 14, 2003 12:12
 
----
 
This might be helpful to you in making xmllint work with gvim under Windows,
 
   
  +
[http://code.google.com/p/xmllint/downloads/list Download xmllint for Windows]
http://www.pinkjuice.com/vim/vimrc.txt
 
  +
Use the following command, assuming xml file is open in Vim and xmllint.exe is in the same directory as the file:
   
 
:% !xmllint.exe % --format
'''Anonymous'''
 
, January 21, 2003 11:30
 
----
 
Windows:
 
GNU libxml2 libary's xmllint.exe is buggy.
 
   
  +
The first <code>%</code> ensures the content of the open file is replaced with the results of passing through xmllint. The order of the second <code>%</code> and the flag <code>--format</code> is important as otherwise xmllint will try to open a file with the name "--format".
(See http://gnuwin32.sourceforge.net/packages.html)
 
   
  +
====Altenative xmllint Windows binaries and instructions====
Nothing happens. The input is the same as the output.
 
   
  +
'''''Binaries'''''
It does not work on windows, because the xmllint.exe is unusable (at least in this respect).
 
 
*http://www.zlatkovic.com/projects/libxml/
 
*http://www.zlatkovic.com/projects/libxml/binaries.html
   
 
At previous wiki edit, the most recent version was http://www.zlatkovic.com/projects/libxml/libxml2-2.5.8.win32.zip
This is true for June 2003.
 
   
  +
'''''Instructions'''''
The syntax in vim would be easy:
 
   
  +
For instructions see the Windows section under:
Go into the xml-file and type:
 
:! xmllint.exe --format %
 
 
--Klaus
 
 
Klaus Horsten
 
, June 14, 2003 11:05
 
----
 
 
Klaus Horsten wrote:
 
&gt; It does not work on windows, because the xmllint.exe
 
&gt; 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 .
 
 
&gt; The syntax in vim would be easy:
 
&gt;
 
&gt; Go into the xml-file and type:
 
&gt; :! xmllint.exe --format %
 
 
This would do nothing by itself AFAICS.
 
 
Check
 
http://www.pinkjuice.com/howto/vimxml/setup.xml&#35;xmllint ,
 
http://www.pinkjuice.com/howto/vimxml/tasks.xml&#35;prettyprinting and
 
http://www.pinkjuice.com/howto/vimxml/tasks.xml&#35;validation
 
 
Tobi
 
   
 
*http://www.pinkjuice.com/howto/vimxml/setup.xml#xmllint
   
  +
====Other related links====
   
 
*http://www.pinkjuice.com/howto/vimxml/tasks.xml#prettyprinting and
 
*http://www.pinkjuice.com/howto/vimxml/tasks.xml#validation
   
foo--AT--foo.com
 
, July 21, 2003 15:18
 
 
----
 
----
  +
===Alternatives to xmllint===
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.
 
   
  +
====Built-in Search and Replace====
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?
 
   
  +
Seriously consider using Vim's built-in search and replace functionality. See this [[Pretty-formatting_XML]] and the third comment (<code>:%s/></>\r</g</code> , etc).
dsewell--AT--virginia.edu
 
, August 4, 2003 14:35
 
----
 
Hi,
 
   
  +
====(HTML) Tidy====
try
 
http://www.pinkjuice.com/howto/vimxml/tasks.xml&#35;prettyprinting
 
   
 
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:
HTH,
 
Tobi
 
   
 
au FileType xml exe ":silent 1,$!tidy --input-xml true --indent yes 2>/dev/null"
   
 
Here's how you use tidy with xml on Windows:
tobiasreif pinkjuice com
 
, August 21, 2003 14:30
 
----
 
 
I will change the solution described at the above URL since there is a very simple solution to the problem:
 
   
 
au FileType xml exe ":silent 1,$!tidy -q -i -xml"
http://mail.gnome.org/archives/xml/2003-August/msg00017.html
 
http://mail.gnome.org/archives/xml/2003-August/msg00018.html
 
   
 
I have this in my .vimrc
:%!xmllint --format --encode UTF-8 -
 
 
" select xml text to format and hit ,x
 
vmap ,x :!tidy -q -i -xml<CR>
   
Tobi
 
 
 
 
tobiasreif pinkjuice com
 
, August 24, 2003 7:37
 
 
----
 
----
  +
===UTF-8 format===
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.
 
   
 
'''Q:''' 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.
heyspearsy--AT--yahoo.ca
 
, September 16, 2003 7:57
 
----
 
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...
 
   
 
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?
   
   
 
'''A:''' Try http://www.pinkjuice.com/howto/vimxml/tasks.xml#prettyprinting
'''Anonymous'''
 
, June 30, 2004 3:32
 
----
 
I was dissatisfied with what xmllint was doing to my XML documents. Its --format option seems to arbitrarily expand or remove blank lines.
 
   
 
'''A:''' I will change the solution described at the above URL since there is a very simple solution to the problem:
An alternative is to use the tidy program - formerly HTML Tidy. available at http://tidy.sourceforge.net/ I altered my .vimrc as follows:
 
 
*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 -
au FileType xml exe ":silent 1,$!tidy --input-xml true --indent yes 2&gt;/dev/null"
 
   
Much nicer. :)
 
 
jay--AT--infonium.ca
 
, August 14, 2004 7:27
 
 
----
 
----
  +
===Changing tab/ident width===
Here's how you use tidy with xml on Windows:
 
 
'''Q:'''. 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.
 
au FileType xml exe ":silent 1,$!tidy -q -i -xml"
 
 
tom--AT--tompurl.com
 
, August 26, 2006 13:04
 
----
 
I have this in my .vimrc
 
 
"-----
 
" select xml text to format and hit ,x
 
vmap ,x :!tidy -q -i -xml&lt;CR&gt;
 
"---
 
 
 
code __at__ sujee _*dot*_ net
 
, November 17, 2006 11:44
 
----
 
<!-- parsed by vimtips.py in 0.602681 seconds-->
 
 
 
[[Category:XML]]
 
   
  +
'''A:'''. In Unix/Linux, if you don't like the default indentation (2 spaces), set the $XMLLINT_INDENT environment variable, or prefix the xmllint command in your .vimrc file:
[[Category:Syntax]]
 
  +
au FileType xml exe ":silent 1,$!XMLLINT_INDENT=' ' xmllint --format --recover - 2>/dev/null"

Revision as of 12:28, 29 March 2014

Tip 349 Printable Monobook Previous Next

created 2002 · complexity basic · author Daniel Allen · version 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:

au FileType xml exe ":silent %!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 amount 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).

Comments

xmllint as a filter

Q: 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?

A: Notice the '-' given as the file argument to xmllint. This usually means stdin. So, the full command should be:

let &l:equalprg='xmllint --format --recover -'

A: 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.

A: 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>

Fixing indenting of comment lines

"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 line =~ '-->'
        let [lnum,watever] = searchpos('<!--','b')
    else
        break
    endif
endwhile

Alone-on-line end-of-comment closing-tags may get badly indented though.


xmllint on Windows

Download xmllint for Windows Use the following command, assuming xml file is open in Vim and xmllint.exe is in the same directory as the file:

   :% !xmllint.exe % --format

The first % ensures the content of the open file is replaced with the results of passing through xmllint. The order of the second % and the flag --format is important as otherwise xmllint will try to open a file with the name "--format".

Altenative xmllint Windows binaries and instructions

Binaries

At previous wiki edit, the most recent version was http://www.zlatkovic.com/projects/libxml/libxml2-2.5.8.win32.zip

Instructions

For instructions see the Windows section under:

Other related links


Alternatives to xmllint

Built-in Search and Replace

Seriously consider using Vim's built-in search and replace functionality. See this Pretty-formatting_XML and the third comment (:%s/></>\r</g , etc).

(HTML) Tidy

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"

Here's how you use tidy with xml on Windows:

au FileType xml exe ":silent 1,$!tidy -q -i -xml"

I have this in my .vimrc

" select xml text to format and hit ,x
vmap ,x :!tidy -q -i -xml<CR>

UTF-8 format

Q: 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?


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

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

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

Changing tab/ident width

Q:. 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.

A:. In Unix/Linux, if you don't like the default indentation (2 spaces), set the $XMLLINT_INDENT environment variable, or prefix the xmllint command in your .vimrc file:

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