We (in this case me, and my colleague Martijn) are currently writing the Profile validation subsystem for the .NET reference implementation. If you have spent time looking at the Profile specification you can probably sympathise that this is nor an easy task nor a matter of a few days of frantic hacking. In fact, we both consider this to be the perfect task to spent our summertime with, and that’s exactly what we’re doing.
As part of building the validator, we needed a solution to validate both Json and Xml FHIR instances, without writing the infrastructure twice. There are basically two possible scenario’s to handle this:
- Write an abstraction on top of Json and Xml and make the validator work with that (in fact, that’s what I have do with the .NET parsers)
- Use the existing parsers to parse the Json into POCO’s, and serialize them back out to Xml, then validate the Xml.
Although the second approach is certainly feasible, it would mean parsing Json instances into memory structures, and serializing them out, just for validation. It seems like a waste.
XPathNavigator to the rescue
Luckily, .NET has a little know feature that allows us to take the first approach and stay native to the platform: XPathNavigator. This little abstract class allows you to implement a few specific navigation methods over any datastructure, and then pass it to the existing XML infrastructure. Once you’ve done that, you can execute XPath statements and run Xslt stylesheets over your datasource, as if it was Xml in the first place. People have been implementing this interface on top of the Windows Registry, a filesystem, LDAP, you name it.
You’ve probably guessed it: we implemented in on top of Newtonsoft’s popular Json parser . We’ve taken care of all the weird FHIR-specific Json features (like the extensions in _members and irregular mapping to Xml of Binaries), and you can just treat the Json as XML. So, for example, if you take a look at the Patient in this test file, you can now run the following code:
var nav = new JsonXPathNavigator(new JsonTextReader(new StreamReader(file))); var text = nav.SelectSingleNode("/f:Patient/f:telecom/f:use/@value", mgr); Assert.AreEqual("work", text.Value);
Note that I certainly did not write the SelectSingleNode() function, all the Xml infrastructure now just works, even an Xslt transform:
var nav = new JsonXPathNavigator(new JsonTextReader(new StreamReader(file))); XslCompiledTransform xslt = new XslCompiledTransform(); xslt.Load(styleSheet); xslt.Transform(nav, outputStream);
As a result, we can now run the invariants provided in the spec on Json instances and build our validation logic only once.
If you’re interested, you can take a look at the JsonXPathNavigator.cs here. It will be included in the NuGet package on the next release.