Oh man, Day 5? I'm really bad at this. But hey, I was up front that I wouldn't actually be posting on a daily basis.
It's pretty hard to write an application that doesn't touch XML in some way these days. A while ago, I found myself in several situations where I was wishing I could run an XML document through an XSLT before processing it. As a workaround, I'd load the document into an XmlDocument and do the transformation programmatically.
That's obviously a bit of a bitch, so after some thorough digging, I found that Windows Mobile 6+ ships with the unmanaged MSXML API, and that you can create wrappers for these COM objects using the MIDL compiler and adding a reference to the type library file (TLB).
My deterrence from using this is that for everything I write I need to remember to add the COM wrapper, Interop.MSXML2.dll, to my CAB setup files. This isn't a huge deal when it's a single file, obviously. But updating my setup projects every time I add a COM wrapper is very tedious.
Normally, I could just embed that DLL as a resource in my assembly, and call Assembly.Load on the resource stream. However, .NET CF does not have that particular overload of Assembly.Load. So my horrible solution: embed it as a resource, and when the static constructor on XslCompiledTransform is called, write that file out to the current directory and load it:
static XslCompiledTransform() { try { Assembly.LoadFrom("Interop.MSXML2.dll"); } catch (Exception) { string cwd = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase); using (FileStream fs = new FileStream(Path.Combine(cwd, "Interop.MSXML2.dll"), FileMode.Create)) { using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CompactFrameworkExtensions.Interop.MSXML2.dll")) { fs.Copy(stream); } } } }
Note: This may cause "dirty" uninstallation issues.
Oh, that reminds me, the "fs.Copy(stream)" is a handy extension method that allows you to copy the contents of a stream into another.
Usage is pretty straightforward:
Resource1.XML and Resource1.XSL are simply strings that contain the documents.
Click here for the full source to XslCompiledTransform and some other handy extension methods.
0 comments:
Post a Comment