Question
· 17 hr ago

Walking a virtual document's structure

Is there a generic process for "walking" the structure of a virtual document - eg an HL7 message (EnsLib.HL7.Message) or an XML document (EnsLib.EDI.XML.Document).

At least we'd want to be able to visit all "nodes" (HL7 fields or sub-fields, XML nodes) in the virtual document and be able to work out/generate the Property Path (so we could call "GetValueAt"). 

We can just about come up with something generic for HL7, since it only nests down to 4 levels within each segment, though we're using numeric Property Path's at that point rather than symbolic ones (MSH:1.3 etc).

Reading the documentation has not so far cast light! Any pointers welcome. Thanks.

Product version: Caché 2018.1
$ZV: Cache for Windows (x86-64) 2018.1 (Build 184U) Wed Sep 19 2018 09:09:22 EDT
Discussion (4)3
Log in or sign up to continue

I doubt it can be done with a generic process for any VDOC type.

For HL7 to get Virtual Property Path using names ("symbolic ones") you must know and use the "DocType" (that is the schema category and message structure) of the message.

In HL7, for a given HL7 message, it's not clear to me what you need/want as output, you want to visit all nodes/fields....defined? All possible nodes/fields defined in the schema structure? All nodes/fields that contains values?

If you need all possible nodes/fields for a given DocType, then you can get them from the Schema Definition.

Thanks, that's helpful. Our end goal was the perennial XML to JSON conversion conundrum, or HL7 to JSON, and as we're currently stuck on Ensemble 2018, we've not got access to %JSON.Adapter, so we're... limited.

Our immediate goal was, given a particular message/document, visit all nodes holding data within the document (traverse the tree), and do some processing for each node - eg output a JSON representation of the data held at that node so that a JSON serialisation of the whole document can be produced; but the general case, not just the JSON case, is of interest.

Current application is taking an HL7 feed and sending (a subset of) the data in the HL7 and sending to be consumed by a downstream system via a REST web-service. The downstream in this case is being developed by another team within our organisation, and they can take XML - we've built a transformation to extract the relevant data into an EnsLib.EDI.XML.Document, and we've developed an XML schema for the data so we can validate it before sending on. But it would have been easier for them to consume JSON, so we were exploring how to do that - and are conscious that future requirements might include sending JSON rather than XML...

An idea, not sure if it fits in your case, if not...disregard it! 😊

1) Get the schema of your HL7 message (for example "2.5")
2) Loop the segments contained in your HL7 message (this should be fairly easy)
3) For each segment get all the fields defined for that segment on the schema it belongs to and check if contains data

To get all the possible fields of a segment, example for 2.5:PID (demo version):
Set rs = ##class(%ResultSet).%New("EnsLib.HL7.Message:EnumerateSegTypes")
Do rs.Execute("2.5:PID", 4, 1)
Do rs.%Display(",")

This way you should get all virtual path for fields with values in your message.

Repeating fields (like PatientIdentifierList()) of course require some extra coding to get/check them all.

P.S.: I think/guess 4 levels (second param in Execute()) is the maximum, otherwise....increase it.