Guest User

form xslt

a guest
Sep 27th, 2012
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.95 KB | None | 0 0
  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <!--
  4. OpenMRS FormEntry Form HL7 Translation
  5.  
  6. This XSLT is used to translate OpenMRS forms from XML into HL7 2.5 format
  7.  
  8. @author Burke Mamlin, MD
  9. @author Ben Wolfe
  10. @version 1.9.5
  11.  
  12. 1.9.5 - allow for organizing sections under "obs" section
  13. 1.9.4 - add support for message uid (as HL7 control id) and transform of patient.health_center to Discharge to Location (PV1-37)
  14. 1.9.3 - fixed rounding error on timestamp (tenths of seconds getting rounded up, causing "60" seconds in some cases)
  15. 1.9.2 - first generally useful version
  16. -->
  17.  
  18. <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes">
  19. <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
  20.  
  21. <xsl:variable name="SENDING-APPLICATION">FORMENTRY</xsl:variable>
  22. <xsl:variable name="SENDING-FACILITY">AMRS.ELD</xsl:variable>
  23. <xsl:variable name="RECEIVING-APPLICATION">HL7LISTENER</xsl:variable>
  24. <xsl:variable name="RECEIVING-FACILITY">AMRS.ELD</xsl:variable>
  25. <xsl:variable name="PATIENT-AUTHORITY"></xsl:variable> <!-- leave blank for internal id, max 20 characters -->
  26. <!-- for now, must match patient_identifier_type.name -->
  27. <xsl:variable name="FORM-AUTHORITY">AMRS.ELD.FORMID</xsl:variable> <!-- max 20 characters -->
  28.  
  29. <xsl:template match="/">
  30. <xsl:apply-templates />
  31. </xsl:template>
  32.  
  33. <!-- Form template -->
  34. <xsl:template match="form">
  35. <!-- MSH Header -->
  36. <xsl:text>MSH|^~\&amp;</xsl:text> <!-- Message header, field separator, and encoding characters -->
  37. <xsl:text>|</xsl:text> <!-- MSH-3 Sending application -->
  38. <xsl:value-of select="$SENDING-APPLICATION" />
  39. <xsl:text>|</xsl:text> <!-- MSH-4 Sending facility -->
  40. <xsl:value-of select="$SENDING-FACILITY" />
  41. <xsl:text>|</xsl:text> <!-- MSH-5 Receiving application -->
  42. <xsl:value-of select="$RECEIVING-APPLICATION" />
  43. <xsl:text>|</xsl:text> <!-- MSH-6 Receiving facility -->
  44. <xsl:value-of select="$RECEIVING-FACILITY" />
  45. <xsl:text>|</xsl:text> <!-- MSH-7 Date/time message sent -->
  46. <xsl:call-template name="hl7Timestamp">
  47. <xsl:with-param name="date" select="current-dateTime()" />
  48. </xsl:call-template>
  49. <xsl:text>|</xsl:text> <!-- MSH-8 Security -->
  50. <xsl:text>|ORU^R01</xsl:text> <!-- MSH-9 Message type ^ Event type (observation report unsolicited) -->
  51. <xsl:text>|</xsl:text> <!-- MSH-10 Message control ID -->
  52. <xsl:choose>
  53. <xsl:when test="header/uid">
  54. <xsl:value-of select="header/uid" />
  55. </xsl:when>
  56. <xsl:otherwise>
  57. <xsl:value-of select="patient/patient.patient_id" />
  58. <xsl:call-template name="hl7Timestamp">
  59. <xsl:with-param name="date" select="current-dateTime()" />
  60. </xsl:call-template>
  61. </xsl:otherwise>
  62. </xsl:choose>
  63. <xsl:text>|P</xsl:text> <!-- MSH-11 Processing ID -->
  64. <xsl:text>|2.5</xsl:text> <!-- MSH-12 HL7 version -->
  65. <xsl:text>|1</xsl:text> <!-- MSH-13 Message sequence number -->
  66. <xsl:text>|</xsl:text> <!-- MSH-14 Continuation Pointer -->
  67. <xsl:text>|</xsl:text> <!-- MSH-15 Accept Acknowledgement Type -->
  68. <xsl:text>|</xsl:text> <!-- MSH-16 Application Acknowledgement Type -->
  69. <xsl:text>|</xsl:text> <!-- MSH-17 Country Code -->
  70. <xsl:text>|</xsl:text> <!-- MSH-18 Character Set -->
  71. <xsl:text>|</xsl:text> <!-- MSH-19 Principal Language of Message -->
  72. <xsl:text>|</xsl:text> <!-- MSH-20 Alternate Character Set Handling Scheme -->
  73. <xsl:text>|</xsl:text> <!-- MSH-21 Message Profile Identifier -->
  74. <xsl:value-of select="@id" />
  75. <xsl:text>^</xsl:text>
  76. <xsl:value-of select="$FORM-AUTHORITY" />
  77. <xsl:text>&#x000d;</xsl:text>
  78.  
  79. <!-- PID header -->
  80. <xsl:text>PID</xsl:text> <!-- Message type -->
  81. <xsl:text>|</xsl:text> <!-- PID-1 Set ID -->
  82. <xsl:text>|</xsl:text> <!-- PID-2 (deprecated) Patient ID -->
  83. <xsl:text>|</xsl:text> <!-- PID-3 Patient Identifier List -->
  84. <xsl:call-template name="patient_id">
  85. <xsl:with-param name="pid" select="patient/patient.patient_id" />
  86. <xsl:with-param name="auth" select="$PATIENT-AUTHORITY" />
  87. <xsl:with-param name="type" select="L" />
  88. </xsl:call-template>
  89. <xsl:if test="patient/patient.previous_mrn and string-length(patient/patient.previous_mrn) > 0">
  90. <xsl:text>~</xsl:text>
  91. <xsl:call-template name="patient_id">
  92. <xsl:with-param name="pid" select="patient/patient.previous_mrn" />
  93. <xsl:with-param name="auth" select="$PATIENT-AUTHORITY" />
  94. <xsl:with-param name="type" select="PRIOR" />
  95. </xsl:call-template>
  96. </xsl:if>
  97. <!-- Additional patient identifiers -->
  98. <!-- This example is for an MTCT-PLUS identifier used in the AMPATH project in Kenya (skipped if not present) -->
  99. <xsl:if test="patient/patient.mtctplus_id and string-length(patient/patient.mtctplus_id) > 0">
  100. <xsl:text>~</xsl:text>
  101. <xsl:call-template name="patient_id">
  102. <xsl:with-param name="pid" select="patient/patient.mtctplus_id" />
  103. <xsl:with-param name="auth" select="$PATIENT-AUTHORITY" />
  104. <xsl:with-param name="type" select="MTCTPLUS" />
  105. </xsl:call-template>
  106. </xsl:if>
  107. <xsl:text>|</xsl:text> <!-- PID-4 (deprecated) Alternate patient ID -->
  108. <!-- PID-5 Patient name -->
  109. <xsl:text>|</xsl:text> <!-- Family name -->
  110. <xsl:value-of select="patient/patient.family_name" />
  111. <xsl:text>^</xsl:text> <!-- Given name -->
  112. <xsl:value-of select="patient/patient.given_name" />
  113. <xsl:text>^</xsl:text> <!-- Middle name -->
  114. <xsl:value-of select="patient/patient.middle_name" />
  115. <xsl:text>|</xsl:text> <!-- PID-6 Mother's maiden name -->
  116. <xsl:text>|</xsl:text> <!-- PID-7 Date/Time of Birth -->
  117. <xsl:value-of select="patient/patient.date_of_birth" />
  118. <xsl:text>&#x000d;</xsl:text> <!-- new line -->
  119.  
  120. <!-- PV1 header -->
  121. <xsl:text>PV1</xsl:text> <!-- Message type -->
  122. <xsl:text>|</xsl:text> <!-- PV1-1 Sub ID -->
  123. <xsl:text>|O</xsl:text> <!-- PV1-2 Patient class (O = outpatient) -->
  124. <xsl:text>|</xsl:text> <!-- PV1-3 Patient location -->
  125. <xsl:value-of select="encounter/encounter.location_id" />
  126. <xsl:text>|</xsl:text> <!-- PV1-4 Admission type (2 = return) -->
  127. <xsl:text>|</xsl:text> <!-- PV1-5 Pre-Admin Number -->
  128. <xsl:text>|</xsl:text> <!-- PV1-6 Prior Patient Location -->
  129. <xsl:text>|</xsl:text> <!-- PV1-7 Attending Doctor -->
  130. <xsl:value-of select="encounter/encounter.provider_id" />
  131. <xsl:text>|</xsl:text> <!-- PV1-8 Referring Doctor -->
  132. <xsl:text>|</xsl:text> <!-- PV1-9 Consulting Doctor -->
  133. <xsl:text>|</xsl:text> <!-- PV1-10 Hospital Service -->
  134. <xsl:text>|</xsl:text> <!-- PV1-11 Temporary Location -->
  135. <xsl:text>|</xsl:text> <!-- PV1-12 Preadmin Test Indicator -->
  136. <xsl:text>|</xsl:text> <!-- PV1-13 Re-adminssion Indicator -->
  137. <xsl:text>|</xsl:text> <!-- PV1-14 Admit Source -->
  138. <xsl:text>|</xsl:text> <!-- PV1-15 Ambulatory Status -->
  139. <xsl:text>|</xsl:text> <!-- PV1-16 VIP Indicator -->
  140. <xsl:text>|</xsl:text> <!-- PV1-17 Admitting Doctor -->
  141. <xsl:text>|</xsl:text> <!-- PV1-18 Patient Type -->
  142. <xsl:text>|</xsl:text> <!-- PV1-19 Visit Number -->
  143. <xsl:text>|</xsl:text> <!-- PV1-20 Financial Class -->
  144. <xsl:text>|</xsl:text> <!-- PV1-21 Charge Price Indicator -->
  145. <xsl:text>|</xsl:text> <!-- PV1-22 Courtesy Code -->
  146. <xsl:text>|</xsl:text> <!-- PV1-23 Credit Rating -->
  147. <xsl:text>|</xsl:text> <!-- PV1-24 Contract Code -->
  148. <xsl:text>|</xsl:text> <!-- PV1-25 Contract Effective Date -->
  149. <xsl:text>|</xsl:text> <!-- PV1-26 Contract Amount -->
  150. <xsl:text>|</xsl:text> <!-- PV1-27 Contract Period -->
  151. <xsl:text>|</xsl:text> <!-- PV1-28 Interest Code -->
  152. <xsl:text>|</xsl:text> <!-- PV1-29 Transfer to Bad Debt Code -->
  153. <xsl:text>|</xsl:text> <!-- PV1-30 Transfer to Bad Debt Date -->
  154. <xsl:text>|</xsl:text> <!-- PV1-31 Bad Debt Agency Code -->
  155. <xsl:text>|</xsl:text> <!-- PV1-31 Bad Debt Transfer Amount -->
  156. <xsl:text>|</xsl:text> <!-- PV1-33 Bad Debt Recovery Amount -->
  157. <xsl:text>|</xsl:text> <!-- PV1-34 Delete Account Indicator -->
  158. <xsl:text>|</xsl:text> <!-- PV1-35 Delete Account Date -->
  159. <xsl:text>|</xsl:text> <!-- PV1-36 Discharge Disposition -->
  160. <xsl:text>|</xsl:text> <!-- PV1-37 Discharge To Location -->
  161. <xsl:if test="patient/patient.health_center">
  162. <xsl:value-of select="replace(patient/patient.health_center,'\^','&amp;')" />
  163. </xsl:if>
  164. <xsl:text>|</xsl:text> <!-- PV1-38 Diet Type -->
  165. <xsl:text>|</xsl:text> <!-- PV1-39 Servicing Facility -->
  166. <xsl:text>|</xsl:text> <!-- PV1-40 Bed Status -->
  167. <xsl:text>|</xsl:text> <!-- PV1-41 Account Status -->
  168. <xsl:text>|</xsl:text> <!-- PV1-42 Pending Location -->
  169. <xsl:text>|</xsl:text> <!-- PV1-43 Prior Temporary Location -->
  170. <xsl:text>|</xsl:text> <!-- PV1-44 Admit Date/Time -->
  171. <xsl:call-template name="hl7Date">
  172. <xsl:with-param name="date" select="encounter/encounter.encounter_datetime" />
  173. </xsl:call-template>
  174. <xsl:text>|</xsl:text> <!-- PV1-45 Discharge Date/Time -->
  175. <xsl:text>|</xsl:text> <!-- PV1-46 Current Patient Balance -->
  176. <xsl:text>|</xsl:text> <!-- PV1-47 Total Charges -->
  177. <xsl:text>|</xsl:text> <!-- PV1-48 Total Adjustments -->
  178. <xsl:text>|</xsl:text> <!-- PV1-49 Total Payments -->
  179. <xsl:text>|</xsl:text> <!-- PV1-50 Alternate Visit ID -->
  180. <xsl:text>|V</xsl:text> <!-- PV1-51 Visit Indicator -->
  181. <xsl:text>&#x000d;</xsl:text> <!-- new line -->
  182.  
  183. <!-- We use encounter date as the timestamp for each observation -->
  184. <xsl:variable name="encounterTimestamp">
  185. <xsl:call-template name="hl7Date">
  186. <xsl:with-param name="date" select="encounter/encounter.encounter_datetime" />
  187. </xsl:call-template>
  188. </xsl:variable>
  189.  
  190. <!-- ORC Common Order Segment -->
  191. <xsl:text>ORC</xsl:text> <!-- Message type -->
  192. <xsl:text>|RE</xsl:text> <!-- ORC-1 Order Control (RE = obs to follow) -->
  193. <xsl:text>|</xsl:text> <!-- ORC-2 Placer Order Number -->
  194. <xsl:text>|</xsl:text> <!-- ORC-3 Filler Order Number -->
  195. <xsl:text>|</xsl:text> <!-- ORC-4 Placer Group Number -->
  196. <xsl:text>|</xsl:text> <!-- ORC-5 Order Status -->
  197. <xsl:text>|</xsl:text> <!-- ORC-6 Response Flag -->
  198. <xsl:text>|</xsl:text> <!-- ORC-7 Quantity/Timing -->
  199. <xsl:text>|</xsl:text> <!-- ORC-8 Parent -->
  200. <xsl:text>|</xsl:text> <!-- ORC-9 Date/Time of Transaction -->
  201. <xsl:call-template name="hl7Timestamp">
  202. <xsl:with-param name="date" select="xs:dateTime(header/date_entered)" />
  203. </xsl:call-template>
  204. <xsl:text>|</xsl:text> <!-- ORC-10 Entered By -->
  205. <xsl:value-of select="header/enterer" />
  206. <xsl:text>&#x000d;</xsl:text> <!-- new line -->
  207.  
  208. <!-- Observation(s) -->
  209. <!-- <xsl:variable name="obsList" select="obs/*[(@openmrs_concept and value and value/text() != '') or *[@openmrs_concept and text()='true']]" /> -->
  210. <xsl:variable name="obsList" select="obs/*[(@openmrs_concept and value and value/text() != '') or *[@openmrs_concept and text()='true']]|obs/*[not(@openmrs_concept)]/*[(@openmrs_concept and value and value/text() != '') or *[@openmrs_concept and text()='true']]" />
  211. <xsl:variable name="obsListCount" select="count($obsList)" as="xs:integer" />
  212. <!-- Observation OBR -->
  213. <xsl:text>OBR</xsl:text> <!-- Message type -->
  214. <xsl:text>|</xsl:text> <!-- OBR-1 Set ID -->
  215. <xsl:text>1</xsl:text>
  216. <xsl:text>|</xsl:text> <!-- OBR-2 Placer order number -->
  217. <xsl:text>|</xsl:text> <!-- OBR-3 Filler order number -->
  218. <xsl:text>|</xsl:text> <!-- OBR-4 OBR concept -->
  219. <xsl:value-of select="obs/@openmrs_concept" />
  220. <xsl:text>&#x000d;</xsl:text> <!-- new line -->
  221.  
  222. <!-- observation OBXs -->
  223. <xsl:for-each select="$obsList">
  224. <xsl:choose>
  225. <xsl:when test="value">
  226. <xsl:call-template name="obsObx">
  227. <xsl:with-param name="setId" select="position()" />
  228. <xsl:with-param name="datatype" select="@openmrs_datatype" />
  229. <xsl:with-param name="units" select="@openmrs_units" />
  230. <xsl:with-param name="concept" select="@openmrs_concept" />
  231. <xsl:with-param name="date" select="date/text()" />
  232. <xsl:with-param name="time" select="time/text()" />
  233. <xsl:with-param name="value" select="value" />
  234. <xsl:with-param name="encounterTimestamp" select="$encounterTimestamp" />
  235. </xsl:call-template>
  236. </xsl:when>
  237. <xsl:otherwise>
  238. <xsl:variable name="setId" select="position()" />
  239. <xsl:for-each select="*[@openmrs_concept and text() = 'true']">
  240. <xsl:call-template name="obsObx">
  241. <xsl:with-param name="setId" select="$setId" />
  242. <xsl:with-param name="subId" select="concat($setId,position())" />
  243. <xsl:with-param name="datatype" select="../@openmrs_datatype" />
  244. <xsl:with-param name="units" select="../@openmrs_units" />
  245. <xsl:with-param name="concept" select="../@openmrs_concept" />
  246. <xsl:with-param name="date" select="../date/text()" />
  247. <xsl:with-param name="time" select="../time/text()" />
  248. <xsl:with-param name="value" select="@openmrs_concept" />
  249. <xsl:with-param name="encounterTimestamp" select="$encounterTimestamp" />
  250. </xsl:call-template>
  251. </xsl:for-each>
  252. </xsl:otherwise>
  253. </xsl:choose>
  254. </xsl:for-each>
  255.  
  256. <!-- Grouped observation(s) -->
  257. <!-- <xsl:variable name="obsGroupList" select="obs/*[@openmrs_concept and not(date) and *[(@openmrs_concept and value and value/text() != '') or *[@openmrs_concept and text()='true']]]" /> -->
  258. <xsl:variable name="obsGroupList" select="obs/*[@openmrs_concept and not(date) and *[(@openmrs_concept and value and value/text() != '') or *[@openmrs_concept and text()='true']]]|obs/*[not(@openmrs_concept)]/*[@openmrs_concept and not(date) and *[(@openmrs_concept and value and value/text() != '') or *[@openmrs_concept and text()='true']]]" />
  259. <xsl:variable name="obsGroupListCount" select="count($obsGroupList)" as="xs:integer" />
  260. <xsl:for-each select="$obsGroupList">
  261. <!-- Observation OBR -->
  262. <xsl:text>OBR</xsl:text> <!-- Message type -->
  263. <xsl:text>|</xsl:text> <!-- OBR-1 Set ID -->
  264. <xsl:value-of select="$obsListCount + position()" />
  265. <xsl:text>|</xsl:text> <!-- OBR-2 Placer order number -->
  266. <xsl:text>|</xsl:text> <!-- OBR-3 Filler order number -->
  267. <xsl:text>|</xsl:text> <!-- OBR-4 OBR concept -->
  268. <xsl:value-of select="@openmrs_concept" />
  269. <xsl:text>&#x000d;</xsl:text> <!-- new line -->
  270.  
  271. <!-- Generate OBXs -->
  272. <xsl:for-each select="*[(@openmrs_concept and value and value/text() != '') or *[@openmrs_concept and text()='true']]">
  273. <xsl:choose>
  274. <xsl:when test="value">
  275. <xsl:call-template name="obsObx">
  276. <xsl:with-param name="setId" select="position()" />
  277. <xsl:with-param name="subId" select="1" />
  278. <xsl:with-param name="datatype" select="@openmrs_datatype" />
  279. <xsl:with-param name="units" select="@openmrs_units" />
  280. <xsl:with-param name="concept" select="@openmrs_concept" />
  281. <xsl:with-param name="date" select="date/text()" />
  282. <xsl:with-param name="time" select="time/text()" />
  283. <xsl:with-param name="value" select="value" />
  284. <xsl:with-param name="encounterTimestamp" select="$encounterTimestamp" />
  285. </xsl:call-template>
  286. </xsl:when>
  287. <xsl:otherwise>
  288. <xsl:variable name="setId" select="position()" />
  289. <xsl:for-each select="*[@openmrs_concept and text() = 'true']">
  290. <xsl:call-template name="obsObx">
  291. <xsl:with-param name="setId" select="$setId" />
  292. <xsl:with-param name="subId" select="concat('1.',position())" />
  293. <xsl:with-param name="datatype" select="../@openmrs_datatype" />
  294. <xsl:with-param name="units" select="../@openmrs_units" />
  295. <xsl:with-param name="concept" select="../@openmrs_concept" />
  296. <xsl:with-param name="date" select="../date/text()" />
  297. <xsl:with-param name="time" select="../time/text()" />
  298. <xsl:with-param name="value" select="@openmrs_concept" />
  299. <xsl:with-param name="encounterTimestamp" select="$encounterTimestamp" />
  300. </xsl:call-template>
  301. </xsl:for-each>
  302. </xsl:otherwise>
  303. </xsl:choose>
  304. </xsl:for-each>
  305. </xsl:for-each>
  306.  
  307. <!-- Problem list(s) -->
  308. <xsl:variable name="problemList" select="problem_list/*[value[text() != '']]" />
  309. <xsl:variable name="problemListCount" select="count($problemList)" as="xs:integer" />
  310. <xsl:if test="$problemList">
  311. <!-- Problem list OBR -->
  312. <xsl:text>OBR</xsl:text> <!-- Message type -->
  313. <xsl:text>|</xsl:text> <!-- OBR-1 Set ID -->
  314. <xsl:value-of select="$obsListCount + $obsGroupListCount + 1" />
  315. <xsl:text>|</xsl:text> <!-- OBR-2 Placer order number -->
  316. <xsl:text>|</xsl:text> <!-- OBR-3 Filler order number -->
  317. <xsl:text>|</xsl:text> <!-- OBR-4 OBR concept -->
  318. <xsl:value-of select="problem_list/@openmrs_concept" />
  319. <xsl:text>&#x000d;</xsl:text> <!-- new line -->
  320.  
  321. <!-- Problem list OBXs -->
  322. <xsl:for-each select="$problemList">
  323. <xsl:call-template name="obsObx">
  324. <xsl:with-param name="setId" select="position()" />
  325. <xsl:with-param name="datatype" select="'CWE'" />
  326. <xsl:with-param name="concept" select="@openmrs_concept" />
  327. <xsl:with-param name="date" select="date/text()" />
  328. <xsl:with-param name="time" select="time/text()" />
  329. <xsl:with-param name="value" select="value" />
  330. <xsl:with-param name="encounterTimestamp" select="$encounterTimestamp" />
  331. </xsl:call-template>
  332. </xsl:for-each>
  333. </xsl:if>
  334.  
  335. <!-- Orders -->
  336. <xsl:variable name="orderList" select="orders/*[*[@openmrs_concept and ((value and value/text() != '') or *[@openmrs_concept and text() = 'true'])]]" />
  337. <xsl:variable name="orderListCount" select="count($orderList)" as="xs:integer" />
  338. <xsl:for-each select="$orderList">
  339. <!-- Order section OBR -->
  340. <xsl:text>OBR</xsl:text> <!-- Message type -->
  341. <xsl:text>|</xsl:text> <!-- OBR-1 Set ID -->
  342. <xsl:value-of select="$obsListCount + $obsGroupListCount + $problemListCount + 1" />
  343. <xsl:text>|</xsl:text> <!-- OBR-2 Placer order number -->
  344. <xsl:text>|</xsl:text> <!-- OBR-3 Filler order number -->
  345. <xsl:text>|</xsl:text> <!-- OBR-4 OBR concept -->
  346. <xsl:value-of select="@openmrs_concept" />
  347. <xsl:text>&#x000d;</xsl:text> <!-- new line -->
  348.  
  349. <!-- Order OBXs -->
  350. <xsl:for-each select="*[@openmrs_concept and ((value and value/text() != '') or *[@openmrs_concept and text() = 'true'])]">
  351. <xsl:choose>
  352. <xsl:when test="value">
  353. <xsl:call-template name="obsObx">
  354. <xsl:with-param name="setId" select="position()" />
  355. <xsl:with-param name="datatype" select="@openmrs_datatype" />
  356. <xsl:with-param name="units" select="@openmrs_units" />
  357. <xsl:with-param name="concept" select="@openmrs_concept" />
  358. <xsl:with-param name="date" select="date/text()" />
  359. <xsl:with-param name="time" select="time/text()" />
  360. <xsl:with-param name="value" select="value" />
  361. <xsl:with-param name="encounterTimestamp" select="$encounterTimestamp" />
  362. </xsl:call-template>
  363. </xsl:when>
  364. <xsl:otherwise>
  365. <xsl:variable name="setId" select="position()" />
  366. <xsl:for-each select="*[@openmrs_concept and text() = 'true']">
  367. <xsl:call-template name="obsObx">
  368. <xsl:with-param name="setId" select="$setId" />
  369. <xsl:with-param name="subId" select="position()" />
  370. <xsl:with-param name="datatype" select="../@openmrs_datatype" />
  371. <xsl:with-param name="units" select="../@openmrs_units" />
  372. <xsl:with-param name="concept" select="../@openmrs_concept" />
  373. <xsl:with-param name="date" select="../date/text()" />
  374. <xsl:with-param name="time" select="../time/text()" />
  375. <xsl:with-param name="value" select="@openmrs_concept" />
  376. <xsl:with-param name="encounterTimestamp" select="$encounterTimestamp" />
  377. </xsl:call-template>
  378. </xsl:for-each>
  379. </xsl:otherwise>
  380. </xsl:choose>
  381. </xsl:for-each>
  382. </xsl:for-each>
  383.  
  384. </xsl:template>
  385.  
  386. <!-- Patient Identifier (CX) generator -->
  387. <xsl:template name="patient_id">
  388. <xsl:param name="pid" />
  389. <xsl:param name="auth" />
  390. <xsl:param name="type" />
  391. <xsl:value-of select="$pid" />
  392. <xsl:text>^</xsl:text> <!-- Check digit -->
  393. <xsl:text>^</xsl:text> <!-- Check Digit Scheme -->
  394. <xsl:text>^</xsl:text> <!-- Assigning Authority -->
  395. <xsl:value-of select="$auth" />
  396. <xsl:text>^</xsl:text> <!-- Identifier Type -->
  397. <xsl:value-of select="$type" />
  398. </xsl:template>
  399.  
  400. <!-- OBX Generator -->
  401. <xsl:template name="obsObx">
  402. <xsl:param name="setId" required="no"></xsl:param>
  403. <xsl:param name="subId" required="no"></xsl:param>
  404. <xsl:param name="datatype" required="yes" />
  405. <xsl:param name="concept" required="yes" />
  406. <xsl:param name="date" required="no"></xsl:param>
  407. <xsl:param name="time" required="no"></xsl:param>
  408. <xsl:param name="value" required="no"></xsl:param>
  409. <xsl:param name="units" required="no"></xsl:param>
  410. <xsl:param name="encounterTimestamp" required="yes" />
  411. <xsl:text>OBX</xsl:text> <!-- Message type -->
  412. <xsl:text>|</xsl:text> <!-- Set ID -->
  413. <xsl:value-of select="$setId" />
  414. <xsl:text>|</xsl:text> <!-- Observation datatype -->
  415. <xsl:choose>
  416. <xsl:when test="$datatype = 'BIT'">
  417. <xsl:text>NM</xsl:text>
  418. </xsl:when>
  419. <xsl:otherwise>
  420. <xsl:value-of select="$datatype" />
  421. </xsl:otherwise>
  422. </xsl:choose>
  423. <xsl:text>|</xsl:text> <!-- Concept (what was observed -->
  424. <xsl:value-of select="$concept" />
  425. <xsl:text>|</xsl:text> <!-- Sub-ID -->
  426. <xsl:value-of select="$subId" />
  427. <xsl:text>|</xsl:text> <!-- Value -->
  428. <xsl:choose>
  429. <xsl:when test="$datatype = 'TS'">
  430. <xsl:call-template name="hl7Timestamp">
  431. <xsl:with-param name="date" select="$value" />
  432. </xsl:call-template>
  433. </xsl:when>
  434. <xsl:when test="$datatype = 'DT'">
  435. <xsl:call-template name="hl7Date">
  436. <xsl:with-param name="date" select="$value" />
  437. </xsl:call-template>
  438. </xsl:when>
  439. <xsl:when test="$datatype = 'TM'">
  440. <xsl:call-template name="hl7Time">
  441. <xsl:with-param name="time" select="$value" />
  442. </xsl:call-template>
  443. </xsl:when>
  444. <xsl:when test="$datatype = 'BIT'">
  445. <xsl:choose>
  446. <xsl:when test="$value = '0' or upper-case($value) = 'FALSE'">0</xsl:when>
  447. <xsl:otherwise>1</xsl:otherwise>
  448. </xsl:choose>
  449. </xsl:when>
  450. <xsl:otherwise>
  451. <xsl:value-of select="$value" />
  452. </xsl:otherwise>
  453. </xsl:choose>
  454. <xsl:text>|</xsl:text> <!-- Units -->
  455. <xsl:value-of select="$units" />
  456. <xsl:text>|</xsl:text> <!-- Reference range -->
  457. <xsl:text>|</xsl:text> <!-- Abnormal flags -->
  458. <xsl:text>|</xsl:text> <!-- Probability -->
  459. <xsl:text>|</xsl:text> <!-- Nature of abnormal test -->
  460. <xsl:text>|</xsl:text> <!-- Observation result status -->
  461. <xsl:text>|</xsl:text> <!-- Effective date -->
  462. <xsl:text>|</xsl:text> <!-- User defined access checks -->
  463. <xsl:text>|</xsl:text> <!-- Date time of observation -->
  464. <xsl:choose>
  465. <xsl:when test="$date and $time">
  466. <xsl:call-template name="hl7Timestamp">
  467. <xsl:with-param name="date" select="dateTime($date,$time)" />
  468. </xsl:call-template>
  469. </xsl:when>
  470. <xsl:when test="$date">
  471. <xsl:call-template name="hl7Date">
  472. <xsl:with-param name="date" select="$date" />
  473. </xsl:call-template>
  474. </xsl:when>
  475. <xsl:otherwise>
  476. <xsl:value-of select="$encounterTimestamp" />
  477. </xsl:otherwise>
  478. </xsl:choose>
  479. <xsl:text>&#x000d;</xsl:text>
  480. </xsl:template>
  481.  
  482. <!-- Generate HL7-formatted timestamp -->
  483. <xsl:template name="hl7Timestamp">
  484. <xsl:param name="date" />
  485. <xsl:if test="string($date) != ''">
  486. <xsl:value-of select="concat(year-from-dateTime($date),format-number(month-from-dateTime($date),'00'),format-number(day-from-dateTime($date),'00'),format-number(hours-from-dateTime($date),'00'),format-number(minutes-from-dateTime($date),'00'),format-number(floor(seconds-from-dateTime($date)),'00'))" />
  487. </xsl:if>
  488. </xsl:template>
  489.  
  490. <!-- Generate HL7-formatted date -->
  491. <xsl:template name="hl7Date">
  492. <xsl:param name="date" />
  493. <xsl:if test="string($date) != ''">
  494. <xsl:choose>
  495. <xsl:when test="contains(string($date),'T')">
  496. <xsl:call-template name="hl7Date">
  497. <xsl:with-param name="date" select="xs:date(substring-before($date,'T'))" />
  498. </xsl:call-template>
  499. </xsl:when>
  500. <xsl:otherwise>
  501. <xsl:value-of select="concat(year-from-date($date),format-number(month-from-date($date),'00'),format-number(day-from-date($date),'00'))" />
  502. </xsl:otherwise>
  503. </xsl:choose>
  504. </xsl:if>
  505. </xsl:template>
  506.  
  507. <!-- Generate HL7-formatted time -->
  508. <xsl:template name="hl7Time">
  509. <xsl:param name="time" />
  510. <xsl:if test="$time != ''">
  511. <xsl:value-of select="concat(format-number(hours-from-time($time),'00'),format-number(minutes-from-time($time),'00'),format-number(floor(seconds-from-time($time)),'00'))" />
  512. </xsl:if>
  513. </xsl:template>
  514.  
  515. </xsl:stylesheet>
Advertisement
Add Comment
Please, Sign In to add comment