Transform XML
The decoded XML works with the Logic Apps Transform XML action (XSLT maps in Artifacts/Maps, which is also what the Data Mapper produces). Declare the root namespace with a prefix; child elements have no namespace:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://lambogenius.com/HealthCare/HL7/2X" exclude-result-prefixes="ns0">
<xsl:template match="/ns0:ADT_A01_25">
<Patient>
<Id><xsl:value-of select="PID_PatientIdentification/PID_3_PatientIdentifierList[1]/CX_0_IdNumber"/></Id>
<Family><xsl:value-of select="PID_PatientIdentification/PID_5_PatientName[1]/XPN_0_FamilyName/XPN_0_0_Surname"/></Family>
<Given><xsl:value-of select="PID_PatientIdentification/PID_5_PatientName[1]/XPN_1_GivenName"/></Given>
</Patient>
</xsl:template>
</xsl:stylesheet>XPath in expressions
Each of these ran against the decoded ADT_A01_25 message from the introduction and returned the value shown:
@body('Decode_HL7')?['messages']?[0]?['controlId'] → "MSG00001"
@xpath(xml(body('Decode_HL7')?['xml']), 'string(/*/MSH/MSH_10_MessageControlId)') → "MSG00001"
@xpath(xml(body('Decode_HL7')?['xml']), 'string(/*/MSH/MSH_9_MessageType/CM_MSG_1_TriggerEvent)') → "A01"
@xpath(xml(body('Decode_HL7')?['xml']), 'string(/*/PID_PatientIdentification/PID_3_PatientIdentifierList[1]/CX_0_IdNumber)') → "123456"
@xpath(xml(body('Decode_HL7')?['xml']), 'string(/*/PID_PatientIdentification/PID_5_PatientName[1]/XPN_0_FamilyName/XPN_0_0_Surname)') → "DOE"Field paths
The same fields in the XML, in the JSON form, and in the summary properties. The names come from your XSD; these are the generator's.
| HL7 | XPath in xml | Path in json(json) | Summary property |
|---|---|---|---|
| MSH-3 | /*/MSH/MSH_3_SendingApplication/HD_0_NamespaceId | ADT_A01_25.MSH.MSH_3_SendingApplication.HD_0_NamespaceId | sendingApplication |
| MSH-9.2 | /*/MSH/MSH_9_MessageType/CM_MSG_1_TriggerEvent | ADT_A01_25.MSH.MSH_9_MessageType.CM_MSG_1_TriggerEvent | triggerEvent |
| MSH-10 | /*/MSH/MSH_10_MessageControlId | ADT_A01_25.MSH.MSH_10_MessageControlId | controlId |
| MSH-11 | /*/MSH/MSH_11_ProcessingId/PT_0_ProcessingId | ADT_A01_25.MSH.MSH_11_ProcessingId.PT_0_ProcessingId | processingId |
| MSH-12 | /*/MSH/MSH_12_VersionId/VID_0_VersionId | ADT_A01_25.MSH.MSH_12_VersionId.VID_0_VersionId | version |
| PID-3.1 | /*/PID_PatientIdentification/PID_3_PatientIdentifierList[1]/CX_0_IdNumber | …PID_3_PatientIdentifierList[0].CX_0_IdNumber | — |
| PID-5.1.1 | /*/PID_PatientIdentification/PID_5_PatientName[1]/XPN_0_FamilyName/XPN_0_0_Surname | …PID_5_PatientName[0].XPN_0_FamilyName.XPN_0_0_Surname | — |
- Fields are 1-based, as in HL7 (
PID_5_…is PID-5). Components and sub-components are 0-based (XPN_0_FamilyNameis PID-5.1,XPN_0_0_Surnameis PID-5.1.1,CM_MSG_1_TriggerEventis MSH-9.2). - MSH-1 and MSH-2 are elements (
MSH_1_FieldSeparator,MSH_2_EncodingCharacters), so the other MSH fields keep their HL7 numbers. - XPath indexes are 1-based (
[1]); JSON array indexes are 0-based (?[0]). - Use
/*for the root. Only the root is in the namespace, soxpath(), which has no prefix bindings, works withoutlocal-name(). It also works when the same workflow handles several message types or versions (roots such asADT_A01andADT_A01_25). - Moving BizTalk maps: maps written for BizTalk-style names can be reused; paths into the MSH header change, because MSH is now inside the message instead of a separate document.
- Mapping to an outbound message: produce the target message's XML (MSH included) and pass it to Encode.