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...

Thanks @Eduard Lebedyuk , that was helpful. As you describe, headers are not re-used from a previous call. On closer inspection, our confusion arose from the fact that if you provide a set of credentials as a setting on the operation which is implemented by EnsLib.HTTP.OutboundAdapter, even if you don't explicitly set the Basic Authentication headers yourself, they are created for you by the adapter using the provide credentials - we didn't realise this, and so when we removed our own explicit setting of the headers (for testing) we were confused by the headers still arriving in the downstream system!!

With help from WRC, looks like this is something of our own doing - we were using sub-transforms in ways that caused us problems. Our sub-transforms above were outputting whole new XML documents, when at the very least they should have been taking existing partially produced XML from the top-level transform and using that existing document to output. We "solved" the node ordering issue by moving everything into a single transform, so there was no mismatch between top level and sub-transforms.

We've got the same issue, but with an incoming HL7 feed with embedded, encoded characters - would be nice to be able to detect what's coming in, but I take it from this discussion that's not (reliably) possible. Don't really want to scan the whole text of every incoming message to heuristically look for possible encodings. Upstream say/think they are sending UTF-8, but we seem to be getting Window-1252, for the characters we've seen in the (limited) testing. Who knows what will come through the feed once it goes live!

Auto-adjust / design question 4: we'd find this useful, especially if it handles bulk renames - a bunch of classes implementing a data type, all being moved in one go from one place in the class hierarchy to another and all being consistently renamed.

So files X/Y/A.cls, X/Y/B.cls, X/Y/C.cls, and containing classes X.Y.A, X.Y.B, and X.Y.C being moved to Q/P/A.cls and Q.P.A etc. Especially if Properties defined in X.Y.A as "Property pp As X.Y.B" becomes "Property pp As Q.P.B" when renamed.

Closing off an old question for completeness, we never did get Zen working. In the end we used Apache FOP directly:

  • HL7 -> XML as described in the original question
  • call Apache FOP using $ZF(-100,  $$$fopbat, "-xml", XMLfilename, "-xsl", StyleSheetFilename, "-pdf", PDFfilename)

This puts the output PDF onto the filesystem from where, in our solution, it is later picked up for onward transmission to a downstream system.

For the sake of closing off this old question, and to answer my own question, in light of more experience and some testing...

  • side effects of the transformation could, in theory, change the behaviour - but it'd have to be a transformation that had side-effects (eg kept some kind of state across executions, whether in globals or on the filesystem or in some other way)
  • performance could be affected, since transformation is called twice rather than once, but in most cases the difference is likely to be negligible.