Introduction
I have been fascinated with using XMLDocument in C# applications for the past year. I have used XML for local storage and small applications such as Windows services. I like the way they can be easily searched using XPath queries and the way I can load the whole table into a web browser. 
So, it struck me. Could I set up a XmlDocument to be a multiuser database? After all, XML is a schema for a hierarchical (as opposed to a relational) database. In my previous article, I showed how a single windows service could read and update a document using a mutex. But now I want multiple users to have simultaneous access to my document, just like a database. 
The answer, of course is a web service. 
The critical things are how can I load a resource once and how can I have multiple users access it without collisions. 
Well the first part is taken care of by setting my XmlDocument in the class as a static member. 
private static Pool xpd = new Pool(@"c:\xmlbase\pool.xml");
The second is taken care of by using a Mutex to act as a switch to my document. This way, I can read and change my documentation without collisions - just like it was a static member integer or other variable!
private static Mutex 
mut = new Mutex();
There is a trick here.
You will notice that I do not instantiate an XmlDocument, that is because XmlDocument() does not have a constructor to take a file name in directly, it requires me to execute the Load method. And I don't want the web service to load the file each time it is called - I want it to load once, and then update continuously as long as the web service is running and in use! 
I tried using a static constructor directly in the web service, but that loaded each time I called the web service when I tested it in the debugger. 
So, I created a class called Pool:
public class Pool 
{ 
public XmlDocument xd = new XmlDocument(); 
public Pool( string docname) 
{ 
xd.Load ( docname ); 
} 
}
and I instantiate that as a static member of my web service, called DataBourse.asmx. 
So what does a database do that is interesting? Of course, it serves up data. I just want to be really simple here, and I'm sure we can keep extending this prototype, but for simplicities sake, lets just return one node -using SelectSingleNode - for each XPath query. 
So here's my 'select' method:
[ WebMethod] 
public string SelectFromPool(string xpathquery) 
{ 
mut.WaitOne (); 
XmlNode resultNode = xpd.xd.SelectSingleNode (xpathquery); 
mut.ReleaseMutex (); 
return resultNode.InnerText; 
} 
Then, of course we would want an 'update' method, and it's great to use the first method to help the second return a result:
[ WebMethod] 
public string UpdateSelectedNodeInPool(string xpathquery, string updatetext) 
{ 
mut.WaitOne (); 
xpd.xd.SelectSingleNode (xpathquery). InnerText= updatetext; 
mut.ReleaseMutex (); 
return SelectFromPool(xpathquery); 
} 
You can have hours of fun calling UpdateSelectNodeInPool and seeing it updated in SelectFromPool. Load testing has just begun for me. I'm very curious to see how far I can push this little web service. 
Well, it could go on and on. 
I haven't implemented a Delete method yet, and at some point I'll want to persist the document back to disk (when and with what criteria, I do not yet know).