Finally I got a time to fully implement support for XmlResolver in XInclude.NET (see Extending XInclude.NET). Wow, this stuff looks so powerful! A friend of mine is writing an article about using resolvers in System.Xml, so no spoilers here, all I wanted is to illustrate what can be done now using XInclude.NET and custom XmlResolver.
So, somebody wants to include a list of Northwind employees into a report XML document. Yeah, directly from SQL Server database. Here comes XInclude.NET solution: custom XmlResolver, which queries database and returns XmlReader (via SQLXML of course).
report.xml:
<report> <p>Northwind employees:</p> <xi:include href="sqlxml://LOCO055/Northwind?query= SELECT FirstName, LastName FROM Employees FOR XML AUTO" xmlns:xi="http://www.w3.org/2001/XInclude"/> </report>sqlxml:// URI schema is a proprietary schema, supported by my custom XmlResolver. LOCO055 is my SQL Server machine name, Northwind is the database I want to query and query is the query.
Here goes SqlXmlResolver class:
public class SqlXmlResolver : XmlUrlResolver { static string NorthwindConnString = "Provider=SQLOLEDB;Server={0}; database={1};Integrated Security=SSPI"; public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) { if (absoluteUri.Scheme == "sqlxml") { //Extract server and database names from the URI SqlXmlCommand cmd = new SqlXmlCommand(string.Format(NorthwindConnString, absoluteUri.Host, absoluteUri.LocalPath.Substring(1))); cmd.RootTag = "EmployeesList"; //Extract SQL statement from the URI cmd.CommandText = absoluteUri.Query.Split('=')[1].Replace("%20", " "); return cmd.ExecuteXmlReader(); } else return base.GetEntity(absoluteUri, role, ofObjectToReturn); } } }Not really a sophisticated one, just checks if the URI schema is sqlxml:// and then extracts the data from the URI and runs the query via SQLXML plumbing. Then we can read report.xml via XIncludingReader:
XIncludingReader reader = new XIncludingReader("report.xml"); reader.XmlResolver = new SqlXmlResolver(); XPathDocument doc = new XPathDocument(reader); ...And finally the result is:
<report> <p>Northwind employees:</p> <EmployeesList> <Employees FirstName="Nancy" LastName="Davolio"/> <Employees FirstName="Andrew" LastName="Fuller"/> <Employees FirstName="Janet" LastName="Leverling"/> <Employees FirstName="Margaret" LastName="Peacock"/> <Employees FirstName="Steven" LastName="Buchanan"/> <Employees FirstName="Michael" LastName="Suyama"/> <Employees FirstName="Robert" LastName="King"/> <Employees FirstName="Laura" LastName="Callahan"/> <Employees FirstName="Anne" LastName="Dodsworth"/> </EmployeesList> </report>That magic is supported by XInclude.NET version 1.2, which I'm going to release right now. Well, actually I don't think including SQL into URI was a good idea, but bear in mind, that's just a dummy sample to illustrate the power of XmlResolvers. Enjoy!