YAML (short for "YAML Ain't Markup Language" but I simply prefer "Yet Another Markup Language") is a file format that even further simplifies writing structured data files. A while back I struggled with writing measures for the SANER Project because both XML and JSON formats have some minor issues that make it hard to hand code the expressions.
XML sucks because, well, XML sucks. Whitespace is really valuable for formatting code, but XML just wants to make it to be gone.
JSON isn't much better because you have to escape newlines and once again, cannot see your code structure for expressions.
I dinked around a bit with YAML input and output, and now because I'm creating a new measure, wanted to get it working properly, which I have now done, at least in so far as my YAMLParser now correctly round trips from JSON to YAML and back to JSON.
The key to making this work is using Jackson to convert between JSON and YAML, and configuring the YAML quotes right so that strings that look like numbers (e.g., "001") don't get treated incorrectly as numbers when converting between the two.
The methods newYAMLMapper() creates a Jackson YAMLMapper correctly configured.
public static YAMLMapper newYAMLMapper() {
YAMLMapper m = new YAMLMapper();
return
m.enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE)
.disable(YAMLGenerator.Feature.MINIMIZE_QUOTES)
.disable(YAMLGenerator.Feature.USE_PLATFORM_LINE_BREAKS)
.disable(YAMLGenerator.Feature.SPLIT_LINES);
}
Converting from streams and readers works similarly.
The YamlParser class implements IParser. It contains an embedded jsonParser convert resources back and forth between Java classes and JSON formats, and then uses toYaml and fromYaml methods in encodeResourceToString and parseResource methods to read/write in YAML format. It's NOT the most efficient way to read/write YAML to FHIR, but it works (correctly as best I can tell).
All of the setter/getter methods on YamlParser delegate the work to the embedded JsonParser, as shown in the examples below.
@Override
public void setEncodeElementsAppliesToChildResourcesOnly(
boolean theEncodeElementsAppliesToChildResourcesOnly) {
jsonParser.setEncodeElementsAppliesToChildResourcesOnly(
theEncodeElementsAppliesToChildResourcesOnly);
}
@Override
public boolean isEncodeElementsAppliesToChildResourcesOnly() {
return jsonParser.isEncodeElementsAppliesToChildResourcesOnly();
}
No comments:
Post a Comment