You might already have to work with huge XML files. Using regexp searches aren't really handy as you easily get lost in the XML file. I am currently working with a really enormous XML file. I have then written some small Perl and Vim script to search in XML files using XPath. I have been mostly inspired by those pages:


The Perl program mentioned in the first link has been heavily changed to report a clean filename, line number and message to use in the Vim quickfix window. All you need is to copy the Perl script into your PATH and name it xpath (really original name), then copy the .vimrc fragment into your .vimrc file.

Perl script:

#!/usr/bin/env perl

use strict;
use warnings;

use XML::LibXML;

my ( $filename, $xpath, $rname ) = @ARGV;

unless ( defined $rname ) {
$rname = $filename;

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file( $filename );

my $xc = XML::LibXML::XPathContext->new( $doc );
my $nodes = $xc->findnodes( $xpath );

my $found = 0;
foreach my $node ( $nodes->get_nodelist ) {
print $rname, ":", $node->line_number(), " ", $node->nodePath( ) ,"\n";

unless ( $found ) {
print "No XML found matching xpath '$xpath'\n";

.vimrc fragment:

function! XMLMappings()
noremap ;xp :call Xpath()

function! Xpath()
" Needs to get the real file name for the quickfix window
let realname = bufname( "%" )

" Write the buffer to a temp file
let filename = tempname()
let lines = getline( 1, "$" )
call writefile( lines, filename )

let xpath = input("Enter xpath expression: ")

let tmp1=&grepprg
let tmp2=&grepformat
set grepformat=%f:%l\ %m
set grepprg=xpath
exe "grep ".escape(filename, ' \')." \"".xpath."\" ".escape(realname, ' \')
let &grepprg=tmp1
let &grepformat=tmp2


To use this feature, open an XML file and type <leader>xp, then type your XPath expression. <leader> is the '\' key by default but you may have changed it. The Perl script handles the namespaces in the XPath expressions.