I’m working on a project that needs to import a score of financial information using the OFX protocol which are used by Quicken and Money. When I started out on this I was glad to see that these protoocols have been updated to include schema support, so I was hoping that importing data into objects was going to be relative painless.
Unfortunately this is turning out to be not so – I haven’t had any luck getting OFX -> .NET objects to work. After some initial problems getting XSD.EXE to run against the OFX schemas I did get the classes generated, however in the end it turns out that the generated classes do not work correctly with the data that actually get returned. Part of the problem apparently is in the schema itself and how it represents the second level group header items. When I run the deserialization code against downloaded data the deserialization does not fail, but unfortunately it also fails to import the data correctly.
My Schema and XSD skills are fast fading and were never that strong actually – I haven’t worked in angle brackets in a while now <s>. But this demonstrates one of my big frustration with where XML has ended up, in that schemas in the handful of situations where I needed to use them in .NET with rather complex services rarely import directly without major tweaking.
I checked with Christian Wyer who’s been my goto guy on a few XML related issues in the past and his thoughts were that the schema had some qualifying errors and he deftly pinpointed a problem with the schema setting an unqualified elementFormDefault which caused the XSD.EXE to not import the data correctly. Taking his clue I went ahead and added explicit elementFormDefault=”qualified” to the schemas and sure enough that made the import work.
However, the class structure is pure hell… the classes have untyped array element types that one has to iterate through to figure out what type of element you’re dealing with which makes traversing this document not a whole lot easier than using raw XML. In fact it’s probably more difficult because there’s no way to get directly at any given lower level element via . syntax. At least with XML you can use XPath to jump into lower level nodes.
My buddy Peter Bromberg also kindly pointed me at XSDObjGen, which looks like a great tool that provides XSD like functionality for class generation from schema but is much more sophisticated in parsing the schema and inferring .NET style types. It can manage things like arrays/collections and enums and conditional lists much nicer. For example, it properly figured out the generic arrays in OFX and was able to create typed lists instead which is much easier to navigate. When I ran it against the schemas OFX schemas it created much cleaner looking classes that would be relatively easy to use from code. Unfortunately the generated class also failed to work with the XML Serializer. Trying to instantiate the XmlSerializer with the generated type fails immediately with a type mismatch (Can’t convert DateTime to string).
It seems silly that the schemas for this stuff are so horrible. Heck the schemas don’t even provide strong type information for numeric and date data, so even with these mapped classes values still need to be converted. Well, actually it’s no surprise. This stuff originated from Inuit, which has a history of mismanaged APIs. <s>
There appears to be a new OFX version coming up and it looks like the schemas for that version provide a more .NET friendly schema interface, but unfortunately that version is rather incompatible with the 1.x version that most financial providers seem to be using (it looks like 2.x is compatible with 1.x at least).
So I’m curious – has anybody done this sort of OFX parsing in .NET? Searching around I haven’t seen anything. There’s a component from n/software that I’ve looked at but there are, uh… some problems with that as well. They’re looking into the issues, but it’s not terribly confidence inspiring that the first thing I tried breaks their component <s>… (leave it to me, to do that though).
If anybody’s gone down this path of OFX parsing I’d be interested in hearing from you before I head off and do this the brute force way <s>…
Other Posts you might also like