diff --git a/kids/XML_PROCESSING_UTILITIES_2P4.KID b/kids/XML_PROCESSING_UTILITIES_2P4.KID
new file mode 100644
index 0000000..2127110
--- /dev/null
+++ b/kids/XML_PROCESSING_UTILITIES_2P4.KID
@@ -0,0 +1,7122 @@
+KIDS Distribution saved on Jun 15, 2015@16:10:21
+Install file for Enhanced XML Utilities by Sam H. and George L.
+**KIDS**:XML PROCESSING UTILITIES 2.4^
+
+**INSTALL NAME**
+XML PROCESSING UTILITIES 2.4
+"BLD",9824,0)
+XML PROCESSING UTILITIES 2.4^XML PROCESSING UTILITIES^0^3150615^y
+"BLD",9824,1,0)
+^^13^13^3150525^^^^
+"BLD",9824,1,1,0)
+Created by Sam Habiel of the VISTA Expertise Network.
+"BLD",9824,1,2,0)
+
+"BLD",9824,1,3,0)
+This package updates the VISTA XML Parser. It includes all the
+"BLD",9824,1,4,0)
+functionality of the old version.
+"BLD",9824,1,5,0)
+
+"BLD",9824,1,6,0)
+NB: Moved into it's own package file entry.
+"BLD",9824,1,7,0)
+
+"BLD",9824,1,8,0)
+See accompanying documentation.
+"BLD",9824,1,9,0)
+
+"BLD",9824,1,10,0)
+Previous release notes:
+"BLD",9824,1,11,0)
+This package releases a XML parser that was commissioned by the VA
+"BLD",9824,1,12,0)
+architects. Developer documentation can be found on the VistA
+"BLD",9824,1,13,0)
+Documentation Library under Infrastructure in the Kernel ToolKit session.
+"BLD",9824,4,0)
+^9.64PA^950^1
+"BLD",9824,4,950,0)
+950
+"BLD",9824,4,950,222)
+y^y^f^^^^n
+"BLD",9824,4,"B",950,950)
+
+"BLD",9824,6.3)
+14
+"BLD",9824,"ABPKG")
+n
+"BLD",9824,"KRN",0)
+^9.67PA^779.2^22
+"BLD",9824,"KRN",.4,0)
+.4
+"BLD",9824,"KRN",.4,"NM",0)
+^9.68A^^
+"BLD",9824,"KRN",.401,0)
+.401
+"BLD",9824,"KRN",.402,0)
+.402
+"BLD",9824,"KRN",.403,0)
+.403
+"BLD",9824,"KRN",.5,0)
+.5
+"BLD",9824,"KRN",.84,0)
+.84
+"BLD",9824,"KRN",.84,"NM",0)
+^9.68A^49^49
+"BLD",9824,"KRN",.84,"NM",1,0)
+9500001^^0
+"BLD",9824,"KRN",.84,"NM",2,0)
+9500002^^0
+"BLD",9824,"KRN",.84,"NM",3,0)
+9500003^^0
+"BLD",9824,"KRN",.84,"NM",4,0)
+9500004^^0
+"BLD",9824,"KRN",.84,"NM",5,0)
+9500005^^0
+"BLD",9824,"KRN",.84,"NM",6,0)
+9500006^^0
+"BLD",9824,"KRN",.84,"NM",7,0)
+9500007^^0
+"BLD",9824,"KRN",.84,"NM",8,0)
+9500008^^0
+"BLD",9824,"KRN",.84,"NM",9,0)
+9500009^^0
+"BLD",9824,"KRN",.84,"NM",10,0)
+9500010^^0
+"BLD",9824,"KRN",.84,"NM",11,0)
+9500011^^0
+"BLD",9824,"KRN",.84,"NM",12,0)
+9500012^^0
+"BLD",9824,"KRN",.84,"NM",13,0)
+9500013^^0
+"BLD",9824,"KRN",.84,"NM",14,0)
+9500014^^0
+"BLD",9824,"KRN",.84,"NM",15,0)
+9500015^^0
+"BLD",9824,"KRN",.84,"NM",16,0)
+9500016^^0
+"BLD",9824,"KRN",.84,"NM",17,0)
+9500017^^0
+"BLD",9824,"KRN",.84,"NM",18,0)
+9500018^^0
+"BLD",9824,"KRN",.84,"NM",19,0)
+9500019^^0
+"BLD",9824,"KRN",.84,"NM",20,0)
+9500020^^0
+"BLD",9824,"KRN",.84,"NM",21,0)
+9500021^^0
+"BLD",9824,"KRN",.84,"NM",22,0)
+9500022^^0
+"BLD",9824,"KRN",.84,"NM",23,0)
+9500023^^0
+"BLD",9824,"KRN",.84,"NM",24,0)
+9500024^^0
+"BLD",9824,"KRN",.84,"NM",25,0)
+9500025^^0
+"BLD",9824,"KRN",.84,"NM",26,0)
+9500026^^0
+"BLD",9824,"KRN",.84,"NM",27,0)
+9500027^^0
+"BLD",9824,"KRN",.84,"NM",28,0)
+9500028^^0
+"BLD",9824,"KRN",.84,"NM",29,0)
+9500029^^0
+"BLD",9824,"KRN",.84,"NM",30,0)
+9500030^^0
+"BLD",9824,"KRN",.84,"NM",31,0)
+9500031^^0
+"BLD",9824,"KRN",.84,"NM",32,0)
+9500032^^0
+"BLD",9824,"KRN",.84,"NM",33,0)
+9500033^^0
+"BLD",9824,"KRN",.84,"NM",34,0)
+9500034^^0
+"BLD",9824,"KRN",.84,"NM",35,0)
+9500035^^0
+"BLD",9824,"KRN",.84,"NM",36,0)
+9500036^^0
+"BLD",9824,"KRN",.84,"NM",37,0)
+9500037^^0
+"BLD",9824,"KRN",.84,"NM",38,0)
+9500038^^0
+"BLD",9824,"KRN",.84,"NM",39,0)
+9500039^^0
+"BLD",9824,"KRN",.84,"NM",40,0)
+9500040^^0
+"BLD",9824,"KRN",.84,"NM",41,0)
+9500041^^0
+"BLD",9824,"KRN",.84,"NM",42,0)
+9500042^^0
+"BLD",9824,"KRN",.84,"NM",43,0)
+9500043^^0
+"BLD",9824,"KRN",.84,"NM",44,0)
+9500044^^0
+"BLD",9824,"KRN",.84,"NM",45,0)
+9500045^^0
+"BLD",9824,"KRN",.84,"NM",46,0)
+9500046^^0
+"BLD",9824,"KRN",.84,"NM",47,0)
+9500047^^0
+"BLD",9824,"KRN",.84,"NM",48,0)
+9500048^^0
+"BLD",9824,"KRN",.84,"NM",49,0)
+9500049^^0
+"BLD",9824,"KRN",.84,"NM","B",9500001,1)
+
+"BLD",9824,"KRN",.84,"NM","B",9500002,2)
+
+"BLD",9824,"KRN",.84,"NM","B",9500003,3)
+
+"BLD",9824,"KRN",.84,"NM","B",9500004,4)
+
+"BLD",9824,"KRN",.84,"NM","B",9500005,5)
+
+"BLD",9824,"KRN",.84,"NM","B",9500006,6)
+
+"BLD",9824,"KRN",.84,"NM","B",9500007,7)
+
+"BLD",9824,"KRN",.84,"NM","B",9500008,8)
+
+"BLD",9824,"KRN",.84,"NM","B",9500009,9)
+
+"BLD",9824,"KRN",.84,"NM","B",9500010,10)
+
+"BLD",9824,"KRN",.84,"NM","B",9500011,11)
+
+"BLD",9824,"KRN",.84,"NM","B",9500012,12)
+
+"BLD",9824,"KRN",.84,"NM","B",9500013,13)
+
+"BLD",9824,"KRN",.84,"NM","B",9500014,14)
+
+"BLD",9824,"KRN",.84,"NM","B",9500015,15)
+
+"BLD",9824,"KRN",.84,"NM","B",9500016,16)
+
+"BLD",9824,"KRN",.84,"NM","B",9500017,17)
+
+"BLD",9824,"KRN",.84,"NM","B",9500018,18)
+
+"BLD",9824,"KRN",.84,"NM","B",9500019,19)
+
+"BLD",9824,"KRN",.84,"NM","B",9500020,20)
+
+"BLD",9824,"KRN",.84,"NM","B",9500021,21)
+
+"BLD",9824,"KRN",.84,"NM","B",9500022,22)
+
+"BLD",9824,"KRN",.84,"NM","B",9500023,23)
+
+"BLD",9824,"KRN",.84,"NM","B",9500024,24)
+
+"BLD",9824,"KRN",.84,"NM","B",9500025,25)
+
+"BLD",9824,"KRN",.84,"NM","B",9500026,26)
+
+"BLD",9824,"KRN",.84,"NM","B",9500027,27)
+
+"BLD",9824,"KRN",.84,"NM","B",9500028,28)
+
+"BLD",9824,"KRN",.84,"NM","B",9500029,29)
+
+"BLD",9824,"KRN",.84,"NM","B",9500030,30)
+
+"BLD",9824,"KRN",.84,"NM","B",9500031,31)
+
+"BLD",9824,"KRN",.84,"NM","B",9500032,32)
+
+"BLD",9824,"KRN",.84,"NM","B",9500033,33)
+
+"BLD",9824,"KRN",.84,"NM","B",9500034,34)
+
+"BLD",9824,"KRN",.84,"NM","B",9500035,35)
+
+"BLD",9824,"KRN",.84,"NM","B",9500036,36)
+
+"BLD",9824,"KRN",.84,"NM","B",9500037,37)
+
+"BLD",9824,"KRN",.84,"NM","B",9500038,38)
+
+"BLD",9824,"KRN",.84,"NM","B",9500039,39)
+
+"BLD",9824,"KRN",.84,"NM","B",9500040,40)
+
+"BLD",9824,"KRN",.84,"NM","B",9500041,41)
+
+"BLD",9824,"KRN",.84,"NM","B",9500042,42)
+
+"BLD",9824,"KRN",.84,"NM","B",9500043,43)
+
+"BLD",9824,"KRN",.84,"NM","B",9500044,44)
+
+"BLD",9824,"KRN",.84,"NM","B",9500045,45)
+
+"BLD",9824,"KRN",.84,"NM","B",9500046,46)
+
+"BLD",9824,"KRN",.84,"NM","B",9500047,47)
+
+"BLD",9824,"KRN",.84,"NM","B",9500048,48)
+
+"BLD",9824,"KRN",.84,"NM","B",9500049,49)
+
+"BLD",9824,"KRN",3.6,0)
+3.6
+"BLD",9824,"KRN",3.8,0)
+3.8
+"BLD",9824,"KRN",9.2,0)
+9.2
+"BLD",9824,"KRN",9.8,0)
+9.8
+"BLD",9824,"KRN",9.8,"NM",0)
+^9.68A^13^13
+"BLD",9824,"KRN",9.8,"NM",1,0)
+MXMLPRS0^^0^B73523150
+"BLD",9824,"KRN",9.8,"NM",2,0)
+MXMLPRS1^^0^B16479083
+"BLD",9824,"KRN",9.8,"NM",3,0)
+MXMLPRSE^^0^B70461009
+"BLD",9824,"KRN",9.8,"NM",4,0)
+MXMLTEST^^0^B8707097
+"BLD",9824,"KRN",9.8,"NM",5,0)
+MXMLDOM^^0^B8594939
+"BLD",9824,"KRN",9.8,"NM",6,0)
+MXMLBLD^^0^B69832518
+"BLD",9824,"KRN",9.8,"NM",7,0)
+MXMLPATH^^0^B98631514
+"BLD",9824,"KRN",9.8,"NM",8,0)
+MXMLPATT^^0^B211415201
+"BLD",9824,"KRN",9.8,"NM",9,0)
+MXMLTMP1^^0^B66774409
+"BLD",9824,"KRN",9.8,"NM",10,0)
+MXMLTMPL^^0^B114389492
+"BLD",9824,"KRN",9.8,"NM",11,0)
+MXMLTMPT^^0^B204284292
+"BLD",9824,"KRN",9.8,"NM",12,0)
+MXMLUTL^^0^B1746066
+"BLD",9824,"KRN",9.8,"NM",13,0)
+MXMLDOMT^^0^B43422564
+"BLD",9824,"KRN",9.8,"NM","B","MXMLBLD",6)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLDOM",5)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLDOMT",13)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLPATH",7)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLPATT",8)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLPRS0",1)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLPRS1",2)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLPRSE",3)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLTEST",4)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLTMP1",9)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLTMPL",10)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLTMPT",11)
+
+"BLD",9824,"KRN",9.8,"NM","B","MXMLUTL",12)
+
+"BLD",9824,"KRN",19,0)
+19
+"BLD",9824,"KRN",19,"NM",0)
+^9.68A^^
+"BLD",9824,"KRN",19.1,0)
+19.1
+"BLD",9824,"KRN",101,0)
+101
+"BLD",9824,"KRN",409.61,0)
+409.61
+"BLD",9824,"KRN",771,0)
+771
+"BLD",9824,"KRN",779.2,0)
+779.2
+"BLD",9824,"KRN",869.2,0)
+869.2
+"BLD",9824,"KRN",870,0)
+870
+"BLD",9824,"KRN",8989.51,0)
+8989.51
+"BLD",9824,"KRN",8989.52,0)
+8989.52
+"BLD",9824,"KRN",8994,0)
+8994
+"BLD",9824,"KRN",8994.2,0)
+8994.2
+"BLD",9824,"KRN",8994.2,"NM",0)
+^9.68A^^
+"BLD",9824,"KRN","B",.4,.4)
+
+"BLD",9824,"KRN","B",.401,.401)
+
+"BLD",9824,"KRN","B",.402,.402)
+
+"BLD",9824,"KRN","B",.403,.403)
+
+"BLD",9824,"KRN","B",.5,.5)
+
+"BLD",9824,"KRN","B",.84,.84)
+
+"BLD",9824,"KRN","B",3.6,3.6)
+
+"BLD",9824,"KRN","B",3.8,3.8)
+
+"BLD",9824,"KRN","B",9.2,9.2)
+
+"BLD",9824,"KRN","B",9.8,9.8)
+
+"BLD",9824,"KRN","B",19,19)
+
+"BLD",9824,"KRN","B",19.1,19.1)
+
+"BLD",9824,"KRN","B",101,101)
+
+"BLD",9824,"KRN","B",409.61,409.61)
+
+"BLD",9824,"KRN","B",771,771)
+
+"BLD",9824,"KRN","B",779.2,779.2)
+
+"BLD",9824,"KRN","B",869.2,869.2)
+
+"BLD",9824,"KRN","B",870,870)
+
+"BLD",9824,"KRN","B",8989.51,8989.51)
+
+"BLD",9824,"KRN","B",8989.52,8989.52)
+
+"BLD",9824,"KRN","B",8994,8994)
+
+"BLD",9824,"KRN","B",8994.2,8994.2)
+
+"BLD",9824,"QUES",0)
+^9.62^^
+"BLD",9824,"REQB",0)
+^9.611^^
+"FIA",950)
+XML ENTITY CATALOG
+"FIA",950,0)
+^MXML(950,
+"FIA",950,0,0)
+950
+"FIA",950,0,1)
+y^y^f^^^^n
+"FIA",950,0,10)
+
+"FIA",950,0,11)
+
+"FIA",950,0,"RLRO")
+
+"FIA",950,0,"VR")
+2.4^XML PROCESSING UTILITIES
+"FIA",950,950)
+0
+"FIA",950,950.01)
+0
+"KRN",.84,9500001,-1)
+0^1
+"KRN",.84,9500001,0)
+9500001^1^^
+"KRN",.84,9500001,2,0)
+^^1^1^2991115
+"KRN",.84,9500001,2,1,0)
+Expected whitespace
+"KRN",.84,9500002,-1)
+0^2
+"KRN",.84,9500002,0)
+9500002^1^^
+"KRN",.84,9500002,2,0)
+^^1^1^2991115
+"KRN",.84,9500002,2,1,0)
+Invalid name token
+"KRN",.84,9500003,-1)
+0^3
+"KRN",.84,9500003,0)
+9500003^1^^
+"KRN",.84,9500003,2,0)
+^^1^1^2991115
+"KRN",.84,9500003,2,1,0)
+Expected token not found
+"KRN",.84,9500004,-1)
+0^4
+"KRN",.84,9500004,0)
+9500004^3^^
+"KRN",.84,9500004,2,0)
+^^1^1^2991115
+"KRN",.84,9500004,2,1,0)
+Redeclared attribute ignored
+"KRN",.84,9500005,-1)
+0^5
+"KRN",.84,9500005,0)
+9500005^1^^
+"KRN",.84,9500005,2,0)
+^^1^1^2991115
+"KRN",.84,9500005,2,1,0)
+End element has no corresponding start element
+"KRN",.84,9500006,-1)
+0^6
+"KRN",.84,9500006,0)
+9500006^1^^
+"KRN",.84,9500006,2,0)
+^^1^1^2991115
+"KRN",.84,9500006,2,1,0)
+Invalid at top level of document
+"KRN",.84,9500007,-1)
+0^7
+"KRN",.84,9500007,0)
+9500007^1^^
+"KRN",.84,9500007,2,0)
+^^1^1^2991115
+"KRN",.84,9500007,2,1,0)
+Section was not closed
+"KRN",.84,9500008,-1)
+0^8
+"KRN",.84,9500008,0)
+9500008^3^^
+"KRN",.84,9500008,2,0)
+^^1^1^2991115
+"KRN",.84,9500008,2,1,0)
+Element not closed
+"KRN",.84,9500009,-1)
+0^9
+"KRN",.84,9500009,0)
+9500009^1^^
+"KRN",.84,9500009,2,0)
+^^1^1^2991115
+"KRN",.84,9500009,2,1,0)
+Reserved word
+"KRN",.84,9500010,-1)
+0^10
+"KRN",.84,9500010,0)
+9500010^1^^
+"KRN",.84,9500010,2,0)
+^^1^1^2991115
+"KRN",.84,9500010,2,1,0)
+XML version not supported
+"KRN",.84,9500011,-1)
+0^11
+"KRN",.84,9500011,0)
+9500011^1^^
+"KRN",.84,9500011,2,0)
+^^1^1^2991115
+"KRN",.84,9500011,2,1,0)
+No opening quote
+"KRN",.84,9500012,-1)
+0^12
+"KRN",.84,9500012,0)
+9500012^1^^
+"KRN",.84,9500012,2,0)
+^^1^1^2991115
+"KRN",.84,9500012,2,1,0)
+No closing quote
+"KRN",.84,9500013,-1)
+0^13
+"KRN",.84,9500013,0)
+9500013^1^^
+"KRN",.84,9500013,2,0)
+^^1^1^2991115
+"KRN",.84,9500013,2,1,0)
+Character not allowed in literal
+"KRN",.84,9500014,-1)
+0^14
+"KRN",.84,9500014,0)
+9500014^1^^
+"KRN",.84,9500014,2,0)
+^^1^1^2991115
+"KRN",.84,9500014,2,1,0)
+Unknown entity reference
+"KRN",.84,9500015,-1)
+0^15
+"KRN",.84,9500015,0)
+9500015^2^^
+"KRN",.84,9500015,2,0)
+^^1^1^2991115
+"KRN",.84,9500015,2,1,0)
+Top level element is not root element
+"KRN",.84,9500016,-1)
+0^16
+"KRN",.84,9500016,0)
+9500016^1^^
+"KRN",.84,9500016,2,0)
+^^1^1^2991115
+"KRN",.84,9500016,2,1,0)
+Unrecognized DTD tag
+"KRN",.84,9500017,-1)
+0^17
+"KRN",.84,9500017,0)
+9500017^1^^
+"KRN",.84,9500017,2,0)
+^^1^1^2991115
+"KRN",.84,9500017,2,1,0)
+Unexpected end of document
+"KRN",.84,9500018,-1)
+0^18
+"KRN",.84,9500018,0)
+9500018^3^^
+"KRN",.84,9500018,2,0)
+^^1^1^2991115
+"KRN",.84,9500018,2,1,0)
+Redeclared entity ignored
+"KRN",.84,9500019,-1)
+0^19
+"KRN",.84,9500019,0)
+9500019^1^^
+"KRN",.84,9500019,2,0)
+^^1^1^2991115
+"KRN",.84,9500019,2,1,0)
+Invalid character reference
+"KRN",.84,9500020,-1)
+0^20
+"KRN",.84,9500020,0)
+9500020^1^^
+"KRN",.84,9500020,2,0)
+^^1^1^2991115
+"KRN",.84,9500020,2,1,0)
+Duplicate element declaration
+"KRN",.84,9500021,-1)
+0^21
+"KRN",.84,9500021,0)
+9500021^1^^
+"KRN",.84,9500021,2,0)
+^^1^1^2991115
+"KRN",.84,9500021,2,1,0)
+Unbalanced parentheses
+"KRN",.84,9500022,-1)
+0^22
+"KRN",.84,9500022,0)
+9500022^1^^
+"KRN",.84,9500022,2,0)
+^^1^1^2991115
+"KRN",.84,9500022,2,1,0)
+Inconsistent operators
+"KRN",.84,9500023,-1)
+0^23
+"KRN",.84,9500023,0)
+9500023^1^^
+"KRN",.84,9500023,2,0)
+^^1^1^2991115
+"KRN",.84,9500023,2,1,0)
+Element name referenced more than once
+"KRN",.84,9500024,-1)
+0^24
+"KRN",.84,9500024,0)
+9500024^2^^
+"KRN",.84,9500024,2,0)
+^^1^1^2991115
+"KRN",.84,9500024,2,1,0)
+Element not allowed by DTD
+"KRN",.84,9500025,-1)
+0^25
+"KRN",.84,9500025,0)
+9500025^2^^
+"KRN",.84,9500025,2,0)
+^^1^1^2991115
+"KRN",.84,9500025,2,1,0)
+Required element is missing
+"KRN",.84,9500026,-1)
+0^26
+"KRN",.84,9500026,0)
+9500026^2^^
+"KRN",.84,9500026,2,0)
+^^1^1^2991115
+"KRN",.84,9500026,2,1,0)
+Element declaration is missing
+"KRN",.84,9500027,-1)
+0^27
+"KRN",.84,9500027,0)
+9500027^2^^
+"KRN",.84,9500027,2,0)
+^^1^1^2991115
+"KRN",.84,9500027,2,1,0)
+PCDATA not allowed by DTD
+"KRN",.84,9500028,-1)
+0^28
+"KRN",.84,9500028,0)
+9500028^2^^
+"KRN",.84,9500028,2,0)
+^^1^1^2991115
+"KRN",.84,9500028,2,1,0)
+Duplicate ID reference not allowed
+"KRN",.84,9500029,-1)
+0^29
+"KRN",.84,9500029,0)
+9500029^2^^
+"KRN",.84,9500029,2,0)
+^^1^1^2991115
+"KRN",.84,9500029,2,1,0)
+Attribute not recognized
+"KRN",.84,9500030,-1)
+0^30
+"KRN",.84,9500030,0)
+9500030^1^^
+"KRN",.84,9500030,2,0)
+^^1^1^2991115
+"KRN",.84,9500030,2,1,0)
+Could not locate external entity
+"KRN",.84,9500031,-1)
+0^31
+"KRN",.84,9500031,0)
+9500031^3^^
+"KRN",.84,9500031,2,0)
+^^1^1^2991115
+"KRN",.84,9500031,2,1,0)
+Document does not begin with ?xml
+"KRN",.84,9500032,-1)
+0^32
+"KRN",.84,9500032,0)
+9500032^3^^
+"KRN",.84,9500032,2,0)
+^^1^1^2991115
+"KRN",.84,9500032,2,1,0)
+Document does not contain DOCTYPE declaration
+"KRN",.84,9500033,-1)
+0^33
+"KRN",.84,9500033,0)
+9500033^1^^
+"KRN",.84,9500033,2,0)
+^^1^1^2991115
+"KRN",.84,9500033,2,1,0)
+Expected attribute type keyword
+"KRN",.84,9500034,-1)
+0^34
+"KRN",.84,9500034,0)
+9500034^1^^
+"KRN",.84,9500034,2,0)
+^^1^1^2991115
+"KRN",.84,9500034,2,1,0)
+Only IMPLIED or REQUIRED allowed for ID attribute type
+"KRN",.84,9500035,-1)
+0^35
+"KRN",.84,9500035,0)
+9500035^2^^
+"KRN",.84,9500035,2,0)
+^^1^1^2991115
+"KRN",.84,9500035,2,1,0)
+Only one attribute per element can have ID type
+"KRN",.84,9500036,-1)
+0^36
+"KRN",.84,9500036,0)
+9500036^2^^
+"KRN",.84,9500036,2,0)
+^^1^1^2991115
+"KRN",.84,9500036,2,1,0)
+Required attribute is missing
+"KRN",.84,9500037,-1)
+0^37
+"KRN",.84,9500037,0)
+9500037^2^^
+"KRN",.84,9500037,2,0)
+^^1^1^2991115
+"KRN",.84,9500037,2,1,0)
+Attribute value does not match fixed value
+"KRN",.84,9500038,-1)
+0^38
+"KRN",.84,9500038,0)
+9500038^2^^
+"KRN",.84,9500038,2,0)
+^^1^1^2991115
+"KRN",.84,9500038,2,1,0)
+Invalid attribute value
+"KRN",.84,9500039,-1)
+0^39
+"KRN",.84,9500039,0)
+9500039^1^^
+"KRN",.84,9500039,2,0)
+^^1^1^2991115
+"KRN",.84,9500039,2,1,0)
+Expected SYSTEM or PUBLIC identifier
+"KRN",.84,9500040,-1)
+0^40
+"KRN",.84,9500040,0)
+9500040^1^^
+"KRN",.84,9500040,2,0)
+^^1^1^2991115
+"KRN",.84,9500040,2,1,0)
+Illegal reference to unparsed external entity
+"KRN",.84,9500041,-1)
+0^41
+"KRN",.84,9500041,0)
+9500041^1^^
+"KRN",.84,9500041,2,0)
+^^1^1^2991115
+"KRN",.84,9500041,2,1,0)
+Expected INCLUDE or IGNORE
+"KRN",.84,9500042,-1)
+0^42
+"KRN",.84,9500042,0)
+9500042^1^^
+"KRN",.84,9500042,2,0)
+^^1^1^2991115
+"KRN",.84,9500042,2,1,0)
+Closing delimiter missing for conditional section
+"KRN",.84,9500043,-1)
+0^43
+"KRN",.84,9500043,0)
+9500043^1^^
+"KRN",.84,9500043,2,0)
+^^1^1^2991115
+"KRN",.84,9500043,2,1,0)
+Cyclic entity reference
+"KRN",.84,9500044,-1)
+0^44
+"KRN",.84,9500044,0)
+9500044^1^^
+"KRN",.84,9500044,2,0)
+^^1^1^2991115
+"KRN",.84,9500044,2,1,0)
+Conditional section not allowed in internal subset
+"KRN",.84,9500045,-1)
+0^45
+"KRN",.84,9500045,0)
+9500045^1^^
+"KRN",.84,9500045,2,0)
+^^1^1^2991115
+"KRN",.84,9500045,2,1,0)
+Root element can occur only once
+"KRN",.84,9500046,-1)
+0^46
+"KRN",.84,9500046,0)
+9500046^1^^
+"KRN",.84,9500046,2,0)
+^^1^1^2991115
+"KRN",.84,9500046,2,1,0)
+Notation not declared
+"KRN",.84,9500047,-1)
+0^47
+"KRN",.84,9500047,0)
+9500047^2^^
+"KRN",.84,9500047,2,0)
+^^1^1^2991115
+"KRN",.84,9500047,2,1,0)
+ID reference not found
+"KRN",.84,9500048,-1)
+0^48
+"KRN",.84,9500048,0)
+9500048^2^^
+"KRN",.84,9500048,2,0)
+^^1^1^2991115
+"KRN",.84,9500048,2,1,0)
+Redeclared notation ignored
+"KRN",.84,9500049,-1)
+0^49
+"KRN",.84,9500049,0)
+9500049^2^^
+"KRN",.84,9500049,2,0)
+^^1^1^2991115^
+"KRN",.84,9500049,2,1,0)
+Not an unparsed entity reference
+"MBREQ")
+0
+"ORD",9,.84)
+.84;9;;;EDEOUT^DIFROMSO(.84,DA,"",XPDA);FPRE^DIFROMSI(.84,"",XPDA);EPRE^DIFROMSI(.84,DA,"",XPDA,"",OLDA);;EPOST^DIFROMSI(.84,DA,"",XPDA);DEL^DIFROMSK(.84,"",%)
+"ORD",9,.84,0)
+DIALOG
+"PKG",224,-1)
+1^1
+"PKG",224,0)
+XML PROCESSING UTILITIES^MXML^Utilities to handle XML processing in VISTA.
+"PKG",224,20,0)
+^9.402P^^
+"PKG",224,22,0)
+^9.49I^1^1
+"PKG",224,22,1,0)
+2.4^3150615
+"PKG",224,22,1,1,0)
+^^13^13^3150615
+"PKG",224,22,1,1,1,0)
+Created by Sam Habiel of the VISTA Expertise Network.
+"PKG",224,22,1,1,2,0)
+
+"PKG",224,22,1,1,3,0)
+This package updates the VISTA XML Parser. It includes all the
+"PKG",224,22,1,1,4,0)
+functionality of the old version.
+"PKG",224,22,1,1,5,0)
+
+"PKG",224,22,1,1,6,0)
+NB: Moved into it's own package file entry.
+"PKG",224,22,1,1,7,0)
+
+"PKG",224,22,1,1,8,0)
+See accompanying documentation.
+"PKG",224,22,1,1,9,0)
+
+"PKG",224,22,1,1,10,0)
+Previous release notes:
+"PKG",224,22,1,1,11,0)
+This package releases a XML parser that was commissioned by the VA
+"PKG",224,22,1,1,12,0)
+architects. Developer documentation can be found on the VistA
+"PKG",224,22,1,1,13,0)
+Documentation Library under Infrastructure in the Kernel ToolKit session.
+"PKG",224,"VERSION")
+2.4
+"QUES","XPF1",0)
+Y
+"QUES","XPF1","??")
+^D REP^XPDH
+"QUES","XPF1","A")
+Shall I write over your |FLAG| File
+"QUES","XPF1","B")
+YES
+"QUES","XPF1","M")
+D XPF1^XPDIQ
+"QUES","XPF2",0)
+Y
+"QUES","XPF2","??")
+^D DTA^XPDH
+"QUES","XPF2","A")
+Want my data |FLAG| yours
+"QUES","XPF2","B")
+YES
+"QUES","XPF2","M")
+D XPF2^XPDIQ
+"QUES","XPI1",0)
+YO
+"QUES","XPI1","??")
+^D INHIBIT^XPDH
+"QUES","XPI1","A")
+Want KIDS to INHIBIT LOGONs during the install
+"QUES","XPI1","B")
+NO
+"QUES","XPI1","M")
+D XPI1^XPDIQ
+"QUES","XPM1",0)
+PO^VA(200,:EM
+"QUES","XPM1","??")
+^D MG^XPDH
+"QUES","XPM1","A")
+Enter the Coordinator for Mail Group '|FLAG|'
+"QUES","XPM1","B")
+
+"QUES","XPM1","M")
+D XPM1^XPDIQ
+"QUES","XPO1",0)
+Y
+"QUES","XPO1","??")
+^D MENU^XPDH
+"QUES","XPO1","A")
+Want KIDS to Rebuild Menu Trees Upon Completion of Install
+"QUES","XPO1","B")
+NO
+"QUES","XPO1","M")
+D XPO1^XPDIQ
+"QUES","XPZ1",0)
+Y
+"QUES","XPZ1","??")
+^D OPT^XPDH
+"QUES","XPZ1","A")
+Want to DISABLE Scheduled Options, Menu Options, and Protocols
+"QUES","XPZ1","B")
+NO
+"QUES","XPZ1","M")
+D XPZ1^XPDIQ
+"QUES","XPZ2",0)
+Y
+"QUES","XPZ2","??")
+^D RTN^XPDH
+"QUES","XPZ2","A")
+Want to MOVE routines to other CPUs
+"QUES","XPZ2","B")
+NO
+"QUES","XPZ2","M")
+D XPZ2^XPDIQ
+"RTN")
+13
+"RTN","MXMLBLD")
+0^6^B69832518
+"RTN","MXMLBLD",1,0)
+MXMLBLD ; RWF/RWF-OSEHRA/JPS - Recursive XML Writer ;2015-06-11 04:00 PM
+"RTN","MXMLBLD",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;Jun 15, 2015;Build 14
+"RTN","MXMLBLD",3,0)
+ QUIT
+"RTN","MXMLBLD",4,0)
+ ;
+"RTN","MXMLBLD",5,0)
+ ; Original routine authored by U.S. Department of Veterans Affairs
+"RTN","MXMLBLD",6,0)
+ ; Author Wally Fort
+"RTN","MXMLBLD",7,0)
+ ; ATRIBUTEff written by Sam Habiel in 2014. No copyright claimed.
+"RTN","MXMLBLD",8,0)
+ ;
+"RTN","MXMLBLD",9,0)
+ ; Sam sez: Wally Fort wrote this!
+"RTN","MXMLBLD",10,0)
+ ; How to use:
+"RTN","MXMLBLD",11,0)
+ ; - Call START to start the doucment. Pass G so that the output would be
+"RTN","MXMLBLD",12,0)
+ ; stored for later use; otherwise, it prints to the screen.
+"RTN","MXMLBLD",13,0)
+ ; - Call ITEM for a tag with no children
+"RTN","MXMLBLD",14,0)
+ ; - Call MULTI for a tag with children, passing the routine that will
+"RTN","MXMLBLD",15,0)
+ ; create the children for DOITEM
+"RTN","MXMLBLD",16,0)
+ ; - Call END to close the XML document
+"RTN","MXMLBLD",17,0)
+ ; - Grab the document from ^TMP("MXMLBLD",$J)
+"RTN","MXMLBLD",18,0)
+ ; - Kill that global.
+"RTN","MXMLBLD",19,0)
+ ;
+"RTN","MXMLBLD",20,0)
+ ;
+"RTN","MXMLBLD",21,0)
+ ;DOC - The top level tag
+"RTN","MXMLBLD",22,0)
+ ;DOCTYPE - Want to include a DOCTYPE node
+"RTN","MXMLBLD",23,0)
+ ;FLAG - Set to 'G' to store the output in the global ^TMP("MXMLBLD",$J,
+"RTN","MXMLBLD",24,0)
+ ;NO1ST - Not first; don't generate the XML header if this is true
+"RTN","MXMLBLD",25,0)
+ ;ATT - Attribute list for the first element
+"RTN","MXMLBLD",26,0)
+START(DOC,DOCTYPE,FLAG,NO1ST,ATT) ;Call this once at the begining.
+"RTN","MXMLBLD",27,0)
+ K ^TMP("MXMLBLD",$J)
+"RTN","MXMLBLD",28,0)
+ S ^TMP("MXMLBLD",$J,"DOC")=DOC,^TMP("MXMLBLD",$J,"STK")=0
+"RTN","MXMLBLD",29,0)
+ I $G(FLAG)["G" S ^TMP("MXMLBLD",$J,"CNT")=1
+"RTN","MXMLBLD",30,0)
+ I $G(NO1ST)'=1 D OUTPUT($$XMLHDR)
+"RTN","MXMLBLD",31,0)
+ D:$L($G(DOCTYPE)) OUTPUT("") D OUTPUT("<"_DOC_$$ATT(.ATT)_">")
+"RTN","MXMLBLD",32,0)
+ Q
+"RTN","MXMLBLD",33,0)
+ ;
+"RTN","MXMLBLD",34,0)
+END ;Call this once to close out the document
+"RTN","MXMLBLD",35,0)
+ D OUTPUT(""_$G(^TMP("MXMLBLD",$J,"DOC"))_">")
+"RTN","MXMLBLD",36,0)
+ I '$G(^TMP("MXMLBLD",$J,"CNT")) K ^TMP("MXMLBLD",$J)
+"RTN","MXMLBLD",37,0)
+ K ^TMP("MXMLBLD",$J,"DOC"),^("CNT"),^("STK")
+"RTN","MXMLBLD",38,0)
+ Q
+"RTN","MXMLBLD",39,0)
+ ;
+"RTN","MXMLBLD",40,0)
+ITEM(INDENT,TAG,ATT,VALUE) ;Output a Item
+"RTN","MXMLBLD",41,0)
+ N I,X
+"RTN","MXMLBLD",42,0)
+ S ATT=$G(ATT)
+"RTN","MXMLBLD",43,0)
+ I '$D(VALUE) D OUTPUT($$BLS($G(INDENT))_"<"_TAG_$$ATT(.ATT)_" />") Q
+"RTN","MXMLBLD",44,0)
+ D OUTPUT($$BLS($G(INDENT))_"<"_TAG_$$ATT(.ATT)_">"_$$CHARCHK(VALUE)_""_TAG_">")
+"RTN","MXMLBLD",45,0)
+ Q
+"RTN","MXMLBLD",46,0)
+ ;DOITEM is a callback to output the lower level.
+"RTN","MXMLBLD",47,0)
+MULTI(INDENT,TAG,ATT,DOITEM) ;Output a Multipule
+"RTN","MXMLBLD",48,0)
+ N I,X,S
+"RTN","MXMLBLD",49,0)
+ S ATT=$G(ATT)
+"RTN","MXMLBLD",50,0)
+ D PUSH($G(INDENT),TAG,.ATT)
+"RTN","MXMLBLD",51,0)
+ D @DOITEM
+"RTN","MXMLBLD",52,0)
+ D POP
+"RTN","MXMLBLD",53,0)
+ Q
+"RTN","MXMLBLD",54,0)
+ ;
+"RTN","MXMLBLD",55,0)
+ATT(ATT) ;Output a string of attributes
+"RTN","MXMLBLD",56,0)
+ I $D(ATT)<9 Q ""
+"RTN","MXMLBLD",57,0)
+ N I,S,V
+"RTN","MXMLBLD",58,0)
+ S S="",I=""
+"RTN","MXMLBLD",59,0)
+ F S I=$O(ATT(I)) Q:I="" S S=S_" "_I_"="_$$Q(ATT(I))
+"RTN","MXMLBLD",60,0)
+ Q S
+"RTN","MXMLBLD",61,0)
+ ;
+"RTN","MXMLBLD",62,0)
+Q(X) ;Add Quotes
+"RTN","MXMLBLD",63,0)
+ I X'[$C(34) Q $C(34)_X_$C(34)
+"RTN","MXMLBLD",64,0)
+ ;I X'[$C(39) Q $C(39)_X_$C(39)
+"RTN","MXMLBLD",65,0)
+ N Q,Y,I,Z S Q=$C(34),(Y,Z)=""
+"RTN","MXMLBLD",66,0)
+ ;N Q,Y,I,Z S Q=$C(39),(Y,Z)=""
+"RTN","MXMLBLD",67,0)
+ F I=1:1:$L(X,Q)-1 S Y=Y_$P(X,Q,I)_Q_Q
+"RTN","MXMLBLD",68,0)
+ S Y=Y_$P(X,Q,$L(X,Q))
+"RTN","MXMLBLD",69,0)
+ Q $C(34)_Y_$C(34)
+"RTN","MXMLBLD",70,0)
+ ;Q $C(39)_Y_$C(39)
+"RTN","MXMLBLD",71,0)
+ ;
+"RTN","MXMLBLD",72,0)
+XMLHDR() ; -- provides current XML standard header
+"RTN","MXMLBLD",73,0)
+ Q ""
+"RTN","MXMLBLD",74,0)
+ ;
+"RTN","MXMLBLD",75,0)
+OUTPUT(S) ;Output
+"RTN","MXMLBLD",76,0)
+ N C S C=$G(^TMP("MXMLBLD",$J,"CNT"))
+"RTN","MXMLBLD",77,0)
+ I C S ^TMP("MXMLBLD",$J,C)=S,^TMP("MXMLBLD",$J,"CNT")=C+1 Q
+"RTN","MXMLBLD",78,0)
+ W S,!
+"RTN","MXMLBLD",79,0)
+ Q
+"RTN","MXMLBLD",80,0)
+ ;
+"RTN","MXMLBLD",81,0)
+CHARCHK(STR) ; -- replace xml character limits with entities
+"RTN","MXMLBLD",82,0)
+ N A,I,X,Y,Z,NEWSTR
+"RTN","MXMLBLD",83,0)
+ S (Y,Z)=""
+"RTN","MXMLBLD",84,0)
+ ;IF STR["&" SET NEWSTR=STR DO SET STR=Y_Z
+"RTN","MXMLBLD",85,0)
+ ;. FOR X=1:1 SET Y=Y_$PIECE(NEWSTR,"&",X)_"&",Z=$PIECE(STR,"&",X+1,999) QUIT:Z'["&"
+"RTN","MXMLBLD",86,0)
+ I STR["&" F I=1:1:$L(STR,"&")-1 S STR=$P(STR,"&",1,I)_"&"_$P(STR,"&",I+1,999)
+"RTN","MXMLBLD",87,0)
+ I STR["<" F S STR=$PIECE(STR,"<",1)_"<"_$PIECE(STR,"<",2,99) Q:STR'["<"
+"RTN","MXMLBLD",88,0)
+ I STR[">" F S STR=$PIECE(STR,">",1)_">"_$PIECE(STR,">",2,99) Q:STR'[">"
+"RTN","MXMLBLD",89,0)
+ I STR["'" F S STR=$PIECE(STR,"'",1)_"'"_$PIECE(STR,"'",2,99) Q:STR'["'"
+"RTN","MXMLBLD",90,0)
+ I STR["""" F S STR=$PIECE(STR,"""",1)_"""_$PIECE(STR,"""",2,99) Q:STR'[""""
+"RTN","MXMLBLD",91,0)
+ ;
+"RTN","MXMLBLD",92,0)
+ S STR=$TR(STR,$C(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31))
+"RTN","MXMLBLD",93,0)
+ QUIT STR
+"RTN","MXMLBLD",94,0)
+ ;
+"RTN","MXMLBLD",95,0)
+COMMENT(VAL) ;Add Comments
+"RTN","MXMLBLD",96,0)
+ N I,L
+"RTN","MXMLBLD",97,0)
+ ;I $D($G(VAL))=1 D OUTPUT("") Q
+"RTN","MXMLBLD",98,0)
+ I $D(VAL)#2 D OUTPUT("") Q ;CHANGED BY GPL FOR GTM
+"RTN","MXMLBLD",99,0)
+ S I="",L="")
+"RTN","MXMLBLD",102,0)
+ Q
+"RTN","MXMLBLD",103,0)
+ ;
+"RTN","MXMLBLD",104,0)
+PUSH(INDENT,TAG,ATT) ;Write a TAG and save.
+"RTN","MXMLBLD",105,0)
+ N CNT
+"RTN","MXMLBLD",106,0)
+ S ATT=$G(ATT)
+"RTN","MXMLBLD",107,0)
+ D OUTPUT($$BLS($G(INDENT))_"<"_TAG_$$ATT(.ATT)_">")
+"RTN","MXMLBLD",108,0)
+ S CNT=$G(^TMP("MXMLBLD",$J,"STK"))+1,^TMP("MXMLBLD",$J,"STK")=CNT,^TMP("MXMLBLD",$J,"STK",CNT)=INDENT_"^"_TAG
+"RTN","MXMLBLD",109,0)
+ Q
+"RTN","MXMLBLD",110,0)
+ ;
+"RTN","MXMLBLD",111,0)
+POP ;Write last pushed tag and pop
+"RTN","MXMLBLD",112,0)
+ N CNT,TAG,INDENT,X
+"RTN","MXMLBLD",113,0)
+ S CNT=$G(^TMP("MXMLBLD",$J,"STK")),X=^TMP("MXMLBLD",$J,"STK",CNT),^TMP("MXMLBLD",$J,"STK")=CNT-1
+"RTN","MXMLBLD",114,0)
+ S INDENT=+X,TAG=$P(X,"^",2)
+"RTN","MXMLBLD",115,0)
+ D OUTPUT($$BLS(INDENT)_""_TAG_">")
+"RTN","MXMLBLD",116,0)
+ Q
+"RTN","MXMLBLD",117,0)
+ ;
+"RTN","MXMLBLD",118,0)
+BLS(I) ;Return INDENT string
+"RTN","MXMLBLD",119,0)
+ N S
+"RTN","MXMLBLD",120,0)
+ S S="",I=$G(I) S:I>0 $P(S," ",I)=" "
+"RTN","MXMLBLD",121,0)
+ Q S
+"RTN","MXMLBLD",122,0)
+ ;
+"RTN","MXMLBLD",123,0)
+INDENT() ;Renturn indent level
+"RTN","MXMLBLD",124,0)
+ Q +$G(^TMP("MXMLBLD",$J,"STK"))
+"RTN","MXMLBLD",125,0)
+ ;
+"RTN","MXMLBLD",126,0)
+ ;
+"RTN","MXMLBLD",127,0)
+ ;
+"RTN","MXMLBLD",128,0)
+ ;
+"RTN","MXMLBLD",129,0)
+ ;
+"RTN","MXMLBLD",130,0)
+ ;
+"RTN","MXMLBLD",131,0)
+ ;
+"RTN","MXMLBLD",132,0)
+ ;
+"RTN","MXMLBLD",133,0)
+ ;
+"RTN","MXMLBLD",134,0)
+ ; Alternate way to write XML, mostly written by VEN/SMH.
+"RTN","MXMLBLD",135,0)
+ ;
+"RTN","MXMLBLD",136,0)
+ ;
+"RTN","MXMLBLD",137,0)
+ATRIBUTE(NAME,VALUE) ; VEN/SMH - Stolen from Pharmacy Code
+"RTN","MXMLBLD",138,0)
+ ; @DESC Builds a valid encoded attribute from the name/value pair passed in
+"RTN","MXMLBLD",139,0)
+ ;
+"RTN","MXMLBLD",140,0)
+ ; @NAME The left side of the "name=value" relationship
+"RTN","MXMLBLD",141,0)
+ ; @VALUE The right side of the "name=value" relationship
+"RTN","MXMLBLD",142,0)
+ ;
+"RTN","MXMLBLD",143,0)
+ ; @RETURNS A valid/encoded name value pair
+"RTN","MXMLBLD",144,0)
+ NEW PSS,QT
+"RTN","MXMLBLD",145,0)
+ SET QT=""""
+"RTN","MXMLBLD",146,0)
+ SET PSS("attribute")=NAME_"="_QT_$$SYMENC^MXMLUTL($GET(VALUE))_QT
+"RTN","MXMLBLD",147,0)
+ QUIT PSS("attribute")
+"RTN","MXMLBLD",148,0)
+ ;
+"RTN","MXMLBLD",149,0)
+MKTAG(NAME,ATTRS,TEXT,CLOSE) ; $$ PEP - Make an XML Tag
+"RTN","MXMLBLD",150,0)
+ ; Input:
+"RTN","MXMLBLD",151,0)
+ ; - NAME: XML Tag Name (Value)
+"RTN","MXMLBLD",152,0)
+ ; - ATTRS: Name Value pair of attributes (By Reference)
+"RTN","MXMLBLD",153,0)
+ ; - TEXT: Text to include in the node (Value)
+"RTN","MXMLBLD",154,0)
+ ; - CLOSE: Boolean: Are we closing the tag? (Value)
+"RTN","MXMLBLD",155,0)
+ ; Output: XML as in Toyoda Kiichiro
+"RTN","MXMLBLD",156,0)
+ ;
+"RTN","MXMLBLD",157,0)
+ ; Process optional value inputs
+"RTN","MXMLBLD",158,0)
+ S CLOSE=$GET(CLOSE,1) ; Default - Yes
+"RTN","MXMLBLD",159,0)
+ S TEXT=$$SYMENC^MXMLUTL($GET(TEXT)) ; Default - ""; and encode
+"RTN","MXMLBLD",160,0)
+ S NAME=$$SYMENC^MXMLUTL(NAME) ; encode
+"RTN","MXMLBLD",161,0)
+ ;
+"RTN","MXMLBLD",162,0)
+ ; Define constants we use
+"RTN","MXMLBLD",163,0)
+ N LB S LB="<" ; Left Bracket
+"RTN","MXMLBLD",164,0)
+ N RB S RB=">" ; Right Bracket
+"RTN","MXMLBLD",165,0)
+ N SL S SL="/" ; Slant/Slash
+"RTN","MXMLBLD",166,0)
+ N SP S SP=" " ; Space
+"RTN","MXMLBLD",167,0)
+ ;
+"RTN","MXMLBLD",168,0)
+ ; If the name is a closing tag (like /name), just send that out as
+"RTN","MXMLBLD",169,0)
+ I $E(NAME)=SL Q LB_NAME_RB
+"RTN","MXMLBLD",170,0)
+ ;
+"RTN","MXMLBLD",171,0)
+ ; Otherwise we have an open or complete tag to take care of.
+"RTN","MXMLBLD",172,0)
+ ;
+"RTN","MXMLBLD",173,0)
+ ; Process Attributes
+"RTN","MXMLBLD",174,0)
+ N ATTRSTR S ATTRSTR="" ; Where attributes will all go...
+"RTN","MXMLBLD",175,0)
+ N ITER S ITER="" ; Iterator
+"RTN","MXMLBLD",176,0)
+ F S ITER=$O(ATTRS(ITER)) Q:ITER="" S ATTRSTR=ATTRSTR_$$ATRIBUTE(ITER,ATTRS(ITER))_SP ; concat together w/spaces in between
+"RTN","MXMLBLD",177,0)
+ S ATTRSTR=$E(ATTRSTR,1,$L(ATTRSTR)-1) ; Remove trailing space
+"RTN","MXMLBLD",178,0)
+ ;
+"RTN","MXMLBLD",179,0)
+ N STR ; Build string
+"RTN","MXMLBLD",180,0)
+ ;
+"RTN","MXMLBLD",181,0)
+ ; Process beginning part ---->
+"RTN","MXMLBLD",187,0)
+ . E S STR=STR_RB ; Add >
+"RTN","MXMLBLD",188,0)
+ ;
+"RTN","MXMLBLD",189,0)
+ I $L(TEXT),CLOSE S STR=STR_RB_TEXT_LB_SL_NAME_RB Q STR ; Add >text
+"RTN","MXMLBLD",190,0)
+ E S $EC=",U-INVALID-CALL,"
+"RTN","MXMLBLD",191,0)
+ S $EC=",U-INVALID-CALL,"
+"RTN","MXMLBLD",192,0)
+ QUIT
+"RTN","MXMLBLD",193,0)
+ ;
+"RTN","MXMLBLD",194,0)
+PUT(RETURN,STRING) ; PEP Proc/$$ - Put an XML Line into the RETURN Array
+"RTN","MXMLBLD",195,0)
+ ; Output in RETURN. Adds a line in the next available numeric subscript. ByRef
+"RTN","MXMLBLD",196,0)
+ ; STRING: Value to put in return array. Pass by Value.
+"RTN","MXMLBLD",197,0)
+ ; If called as an extrinsic, the last used subscript is returned.
+"RTN","MXMLBLD",198,0)
+ ;
+"RTN","MXMLBLD",199,0)
+ N CNT S CNT=$O(RETURN(" "),-1) ; Last numberic sub; or zero if none
+"RTN","MXMLBLD",200,0)
+ S CNT=CNT+1 ; next line
+"RTN","MXMLBLD",201,0)
+ S RETURN(CNT)=STRING
+"RTN","MXMLBLD",202,0)
+ QUIT:$QUIT CNT QUIT
+"RTN","MXMLBLD",203,0)
+ ;
+"RTN","MXMLBLD",204,0)
+TEST D:$L($T(EN^%ut))&$L($T(^MXMLTMP1)) EN^%ut($T(+0),1) QUIT
+"RTN","MXMLBLD",205,0)
+ ;
+"RTN","MXMLBLD",206,0)
+TESTPUT ; @TEST - Test PUT
+"RTN","MXMLBLD",207,0)
+ N RTN
+"RTN","MXMLBLD",208,0)
+ D PUT(.RTN,$$XMLHDR())
+"RTN","MXMLBLD",209,0)
+ D PUT(.RTN,$$MKTAG("Book",,"Pride and Prejudice"))
+"RTN","MXMLBLD",210,0)
+ D CHKEQ^%ut(RTN(1),"")
+"RTN","MXMLBLD",211,0)
+ D CHKEQ^%ut(RTN(2),"Pride and Prejudice")
+"RTN","MXMLBLD",212,0)
+ QUIT
+"RTN","MXMLBLD",213,0)
+ ;
+"RTN","MXMLBLD",214,0)
+TESTMK ; @TEST - Test MKTAG
+"RTN","MXMLBLD",215,0)
+ N %1
+"RTN","MXMLBLD",216,0)
+ S %1("type")="japaense"
+"RTN","MXMLBLD",217,0)
+ S %1("origin")="japan"
+"RTN","MXMLBLD",218,0)
+ D CHKEQ^%ut($$MKTAG("name",.%1,"Toyoda",1),"Toyoda")
+"RTN","MXMLBLD",219,0)
+ D CHKEQ^%ut($$MKTAG("name",.%1,"Toyoda"),"Toyoda")
+"RTN","MXMLBLD",220,0)
+ D CHKEQ^%ut($$MKTAG("name",,"Toyoda"),"Toyoda")
+"RTN","MXMLBLD",221,0)
+ D CHKEQ^%ut($$MKTAG("name",.%1),"")
+"RTN","MXMLBLD",222,0)
+ D CHKEQ^%ut($$MKTAG("name",.%1,,0),"")
+"RTN","MXMLBLD",223,0)
+ D CHKEQ^%ut($$MKTAG("/name"),"")
+"RTN","MXMLBLD",224,0)
+ QUIT
+"RTN","MXMLBLD",225,0)
+ ;
+"RTN","MXMLBLD",226,0)
+TESTBLD ; @TEST - Test Wally's XML Builder
+"RTN","MXMLBLD",227,0)
+ N %1 S %1("version")="2.5"
+"RTN","MXMLBLD",228,0)
+ D START("Books",,"G",,.%1)
+"RTN","MXMLBLD",229,0)
+ D CHKEQ^%ut(^TMP("MXMLBLD",$J,1),"")
+"RTN","MXMLBLD",230,0)
+ D CHKEQ^%ut(^TMP("MXMLBLD",$J,2),"")
+"RTN","MXMLBLD",231,0)
+ N %1 S %1("type")="date"
+"RTN","MXMLBLD",232,0)
+ D ITEM(,"LastUpdated",.%1,"3-15-99")
+"RTN","MXMLBLD",233,0)
+ D CHKEQ^%ut(^TMP("MXMLBLD",$J,3),"3-15-99")
+"RTN","MXMLBLD",234,0)
+ D MULTI(,"Book",,"BOOKEAC1")
+"RTN","MXMLBLD",235,0)
+ D MULTI(,"Book",,"BOOKEAC2")
+"RTN","MXMLBLD",236,0)
+ D CHKEQ^%ut(^TMP("MXMLBLD",$J,11),"Sorrows of Young Werther")
+"RTN","MXMLBLD",237,0)
+ D END
+"RTN","MXMLBLD",238,0)
+ D CHKEQ^%ut(^TMP("MXMLBLD",$J,14),"")
+"RTN","MXMLBLD",239,0)
+ ; ZWRITE ^TMP("MXMLBLD",$J,*)
+"RTN","MXMLBLD",240,0)
+ QUIT
+"RTN","MXMLBLD",241,0)
+ ;
+"RTN","MXMLBLD",242,0)
+TESTBLD1 ; Test Wally's XML Builder
+"RTN","MXMLBLD",243,0)
+ N %1 S %1("version")="2.5"
+"RTN","MXMLBLD",244,0)
+ D START^MXMLBLD("Books",,"G",,.%1)
+"RTN","MXMLBLD",245,0)
+ N %1 S %1("type")="date"
+"RTN","MXMLBLD",246,0)
+ D ITEM^MXMLBLD(,"LastUpdated",.%1,"3-15-99")
+"RTN","MXMLBLD",247,0)
+ D MULTI^MXMLBLD(,"Book",,"BOOKEAC1")
+"RTN","MXMLBLD",248,0)
+ D MULTI^MXMLBLD(,"Book",,"BOOKEAC2")
+"RTN","MXMLBLD",249,0)
+ D END^MXMLBLD
+"RTN","MXMLBLD",250,0)
+ ; ZWRITE ^TMP("MXMLBLD",$J,*)
+"RTN","MXMLBLD",251,0)
+ QUIT
+"RTN","MXMLBLD",252,0)
+BOOKEAC1 ; Book 1
+"RTN","MXMLBLD",253,0)
+ D ITEM^MXMLBLD(,"Author",,"AUSTEN,JANE")
+"RTN","MXMLBLD",254,0)
+ D ITEM^MXMLBLD(,"Title",,"PRIDE AND PREJUDICE")
+"RTN","MXMLBLD",255,0)
+ D ITEM^MXMLBLD(,"Description",,"A romantic novel revealing how pride can cloud our better judgement.")
+"RTN","MXMLBLD",256,0)
+ Q
+"RTN","MXMLBLD",257,0)
+BOOKEAC2 ; Book 2
+"RTN","MXMLBLD",258,0)
+ D ITEM^MXMLBLD(,"Author",,"Johann Wolfgang von Goethe")
+"RTN","MXMLBLD",259,0)
+ D ITEM^MXMLBLD(,"Title",,"Sorrows of Young Werther")
+"RTN","MXMLBLD",260,0)
+ D ITEM^MXMLBLD(,"Description",,"A tale of unrequited love leading to the demise of the protagonist.")
+"RTN","MXMLBLD",261,0)
+ Q
+"RTN","MXMLDOM")
+0^5^B8594939
+"RTN","MXMLDOM",1,0)
+MXMLDOM ;SAIC/DKM - XML Parser - DOM model ;2015-05-25 11:45 AM
+"RTN","MXMLDOM",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;June 15, 2015;Build 14
+"RTN","MXMLDOM",3,0)
+ ;=================================================================
+"RTN","MXMLDOM",4,0)
+ ; Author Dr. Douglas Martin for SAIC.
+"RTN","MXMLDOM",5,0)
+ ;
+"RTN","MXMLDOM",6,0)
+ ; This acts as an intermediate client between the event-based XML
+"RTN","MXMLDOM",7,0)
+ ; parser and a client requiring an in-memory document model.
+"RTN","MXMLDOM",8,0)
+EN(DOC,OPTION) ;
+"RTN","MXMLDOM",9,0)
+ N CBK,SUCCESS,LEVEL,NODE,HANDLE
+"RTN","MXMLDOM",10,0)
+ K ^TMP("MXMLERR",$J)
+"RTN","MXMLDOM",11,0)
+ L +^TMP("MXMLDOM",$J):5
+"RTN","MXMLDOM",12,0)
+ E Q 0
+"RTN","MXMLDOM",13,0)
+ S HANDLE=$O(^TMP("MXMLDOM",$J,""),-1)+1,^(HANDLE)=""
+"RTN","MXMLDOM",14,0)
+ L -^TMP("MXMLDOM",$J)
+"RTN","MXMLDOM",15,0)
+ S CBK("STARTELEMENT")="STARTELE^MXMLDOM"
+"RTN","MXMLDOM",16,0)
+ S CBK("ENDELEMENT")="ENDELE^MXMLDOM"
+"RTN","MXMLDOM",17,0)
+ S CBK("COMMENT")="COMMENT^MXMLDOM"
+"RTN","MXMLDOM",18,0)
+ S CBK("CHARACTERS")="CHAR^MXMLDOM"
+"RTN","MXMLDOM",19,0)
+ S CBK("ENDDOCUMENT")="ENDDOC^MXMLDOM"
+"RTN","MXMLDOM",20,0)
+ S CBK("ERROR")="ERROR^MXMLDOM"
+"RTN","MXMLDOM",21,0)
+ S (SUCCESS,LEVEL,LEVEL(0),NODE)=0,OPTION=$G(OPTION,"V1")
+"RTN","MXMLDOM",22,0)
+ D EN^MXMLPRSE(DOC,.CBK,OPTION)
+"RTN","MXMLDOM",23,0)
+ D:'SUCCESS DELETE(HANDLE)
+"RTN","MXMLDOM",24,0)
+ Q $S(SUCCESS:HANDLE,1:0)
+"RTN","MXMLDOM",25,0)
+ ; Start element
+"RTN","MXMLDOM",26,0)
+ ; Create new child node and push info on stack
+"RTN","MXMLDOM",27,0)
+STARTELE(ELE,ATTR) ;
+"RTN","MXMLDOM",28,0)
+ N PARENT
+"RTN","MXMLDOM",29,0)
+ S PARENT=LEVEL(LEVEL),NODE=NODE+1
+"RTN","MXMLDOM",30,0)
+ S:PARENT ^TMP("MXMLDOM",$J,HANDLE,PARENT,"C",NODE)=ELE
+"RTN","MXMLDOM",31,0)
+ S LEVEL=LEVEL+1,LEVEL(LEVEL)=NODE,LEVEL(LEVEL,0)=ELE
+"RTN","MXMLDOM",32,0)
+ S ^TMP("MXMLDOM",$J,HANDLE,NODE)=ELE,^(NODE,"P")=PARENT
+"RTN","MXMLDOM",33,0)
+ M ^("A")=ATTR
+"RTN","MXMLDOM",34,0)
+ Q
+"RTN","MXMLDOM",35,0)
+ ; End element
+"RTN","MXMLDOM",36,0)
+ ; Pops element stack
+"RTN","MXMLDOM",37,0)
+ENDELE(ELE) ;
+"RTN","MXMLDOM",38,0)
+ K LEVEL(LEVEL)
+"RTN","MXMLDOM",39,0)
+ S LEVEL=LEVEL-1
+"RTN","MXMLDOM",40,0)
+ Q
+"RTN","MXMLDOM",41,0)
+ ; Comment data
+"RTN","MXMLDOM",42,0)
+COMMENT(TXT) ;
+"RTN","MXMLDOM",43,0)
+ D TXT("X")
+"RTN","MXMLDOM",44,0)
+ Q
+"RTN","MXMLDOM",45,0)
+ ; Character data
+"RTN","MXMLDOM",46,0)
+CHAR(TXT) ;
+"RTN","MXMLDOM",47,0)
+ D TXT("T")
+"RTN","MXMLDOM",48,0)
+ Q
+"RTN","MXMLDOM",49,0)
+ ; Store comment or character data
+"RTN","MXMLDOM",50,0)
+TXT(SUB) N X,Y,Z
+"RTN","MXMLDOM",51,0)
+ S Y=$O(^TMP("MXMLDOM",$J,HANDLE,LEVEL(LEVEL),SUB,""),-1)
+"RTN","MXMLDOM",52,0)
+ I Y>0,($L($G(^(Y)))+$L(TXT)>200)!($G(BGN)["CDATA") S Y=Y+1 ;*rwf
+"RTN","MXMLDOM",53,0)
+ S:'Y Y=1
+"RTN","MXMLDOM",54,0)
+ F Z=$L(TXT,$C(10)):-1:1 Q:TXT="" D
+"RTN","MXMLDOM",55,0)
+ .S X=$P(TXT,$C(10)),TXT=$P(TXT,$C(10),2,9999)
+"RTN","MXMLDOM",56,0)
+ .S ^(Y)=$G(^(Y))_X
+"RTN","MXMLDOM",57,0)
+ .S:Z>1 Y=Y+1 ;*rwf old .S:Z>1 Y=Y+1,^(Y)=""
+"RTN","MXMLDOM",58,0)
+ Q
+"RTN","MXMLDOM",59,0)
+ ; End of document
+"RTN","MXMLDOM",60,0)
+ENDDOC S SUCCESS=1
+"RTN","MXMLDOM",61,0)
+ Q
+"RTN","MXMLDOM",62,0)
+ ;Error reporting
+"RTN","MXMLDOM",63,0)
+ERROR(ERR) ;
+"RTN","MXMLDOM",64,0)
+ N CNT
+"RTN","MXMLDOM",65,0)
+ S CNT=1+$G(^TMP("MXMLERR",$J)),^($J)=CNT
+"RTN","MXMLDOM",66,0)
+ M ^TMP("MXMLERR",$J,CNT)=ERR
+"RTN","MXMLDOM",67,0)
+ Q
+"RTN","MXMLDOM",68,0)
+ ;
+"RTN","MXMLDOM",69,0)
+ ; Below are the external API calls for the interface
+"RTN","MXMLDOM",70,0)
+ ;
+"RTN","MXMLDOM",71,0)
+ ; Delete document instance
+"RTN","MXMLDOM",72,0)
+DELETE(HANDLE) ;
+"RTN","MXMLDOM",73,0)
+ K ^TMP("MXMLDOM",$J,HANDLE)
+"RTN","MXMLDOM",74,0)
+ Q
+"RTN","MXMLDOM",75,0)
+ ; Name of element at node
+"RTN","MXMLDOM",76,0)
+NAME(HANDLE,NODE) ;
+"RTN","MXMLDOM",77,0)
+ Q $G(^TMP("MXMLDOM",$J,HANDLE,NODE))
+"RTN","MXMLDOM",78,0)
+ ; Node of next child
+"RTN","MXMLDOM",79,0)
+CHILD(HANDLE,PARENT,CHILD) ;
+"RTN","MXMLDOM",80,0)
+ Q +$O(^TMP("MXMLDOM",$J,HANDLE,PARENT,"C",+$G(CHILD)))
+"RTN","MXMLDOM",81,0)
+ ; Node of next sibling
+"RTN","MXMLDOM",82,0)
+SIBLING(HANDLE,NODE) ;
+"RTN","MXMLDOM",83,0)
+ Q +$O(^TMP("MXMLDOM",$J,HANDLE,$$PARENT(HANDLE,NODE),"C",NODE))
+"RTN","MXMLDOM",84,0)
+ ; Parent of node
+"RTN","MXMLDOM",85,0)
+PARENT(HANDLE,NODE) ;
+"RTN","MXMLDOM",86,0)
+ Q +$G(^TMP("MXMLDOM",$J,HANDLE,NODE,"P"))
+"RTN","MXMLDOM",87,0)
+ ; Text associated with node
+"RTN","MXMLDOM",88,0)
+TEXT(HANDLE,NODE,RTN) ;
+"RTN","MXMLDOM",89,0)
+ D GETTXT("T")
+"RTN","MXMLDOM",90,0)
+ Q:$Q $D(@RTN)>1
+"RTN","MXMLDOM",91,0)
+ Q
+"RTN","MXMLDOM",92,0)
+ ; Comment associate with node
+"RTN","MXMLDOM",93,0)
+CMNT(HANDLE,NODE,RTN) ;
+"RTN","MXMLDOM",94,0)
+ D GETTXT("X")
+"RTN","MXMLDOM",95,0)
+ Q:$Q $D(@RTN)>1
+"RTN","MXMLDOM",96,0)
+ Q
+"RTN","MXMLDOM",97,0)
+ ; Retrieve text or comment
+"RTN","MXMLDOM",98,0)
+GETTXT(SUB) ;
+"RTN","MXMLDOM",99,0)
+ K @RTN
+"RTN","MXMLDOM",100,0)
+ M @RTN=^TMP("MXMLDOM",$J,HANDLE,NODE,SUB)
+"RTN","MXMLDOM",101,0)
+ Q
+"RTN","MXMLDOM",102,0)
+ ; Retrieve next attribute
+"RTN","MXMLDOM",103,0)
+ATTRIB(HANDLE,NODE,ATTR) ;
+"RTN","MXMLDOM",104,0)
+ Q $O(^TMP("MXMLDOM",$J,HANDLE,NODE,"A",$G(ATTR)))
+"RTN","MXMLDOM",105,0)
+ ; Retrieve attribute value
+"RTN","MXMLDOM",106,0)
+VALUE(HANDLE,NODE,ATTR) ;
+"RTN","MXMLDOM",107,0)
+ Q $G(^TMP("MXMLDOM",$J,HANDLE,NODE,"A",ATTR))
+"RTN","MXMLDOMT")
+0^13^B43422564
+"RTN","MXMLDOMT",1,0)
+MXMLDOMT ; VEN/SMH - Unit Tests for DOM Parser;2015-05-25 11:36 AM
+"RTN","MXMLDOMT",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;June 15, 2015;Build 14
+"RTN","MXMLDOMT",3,0)
+ ;;
+"RTN","MXMLDOMT",4,0)
+ ; (c) Sam Habiel 2014
+"RTN","MXMLDOMT",5,0)
+ ;
+"RTN","MXMLDOMT",6,0)
+ S IO=$P
+"RTN","MXMLDOMT",7,0)
+ N DIQUIET S DIQUIET=1
+"RTN","MXMLDOMT",8,0)
+ D EN^%ut($T(+0),1)
+"RTN","MXMLDOMT",9,0)
+ QUIT
+"RTN","MXMLDOMT",10,0)
+ ;
+"RTN","MXMLDOMT",11,0)
+XML1 ; @TEST - Parse a regular XML Document--sanity test
+"RTN","MXMLDOMT",12,0)
+ D READ("XML1D")
+"RTN","MXMLDOMT",13,0)
+ N D S D=$$EN^MXMLDOM($NA(^TMP($J)),"WD")
+"RTN","MXMLDOMT",14,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",15,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",16,0)
+ QUIT
+"RTN","MXMLDOMT",17,0)
+XML2 ; @TEST - Parse an XML doc on one line
+"RTN","MXMLDOMT",18,0)
+ D READ("XML2D")
+"RTN","MXMLDOMT",19,0)
+ N D S D=$$EN^MXMLDOM($NA(^TMP($J)),"WD")
+"RTN","MXMLDOMT",20,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",21,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",22,0)
+ QUIT
+"RTN","MXMLDOMT",23,0)
+XML3 ; @TEST - Parse an XML doc broken on several lines
+"RTN","MXMLDOMT",24,0)
+ D READ("XML3D")
+"RTN","MXMLDOMT",25,0)
+ N D S D=$$EN^MXMLDOM($NA(^TMP($J)),"WD")
+"RTN","MXMLDOMT",26,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",27,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",28,0)
+ QUIT
+"RTN","MXMLDOMT",29,0)
+XML4 ; @TEST - Parse an XML doc with Character ref attr
+"RTN","MXMLDOMT",30,0)
+ D READ("XML4D")
+"RTN","MXMLDOMT",31,0)
+ N D S D=$$EN^MXMLDOM($NA(^TMP($J)),"WD")
+"RTN","MXMLDOMT",32,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",33,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",34,0)
+ QUIT
+"RTN","MXMLDOMT",35,0)
+XML5 ; @TEST - Parse an XML doc with Chracter ref attr broken over 2 lines (Sergey's bug)
+"RTN","MXMLDOMT",36,0)
+ D READ("XML5D")
+"RTN","MXMLDOMT",37,0)
+ N D S D=$$EN^MXMLDOM($NA(^TMP($J)),"WD")
+"RTN","MXMLDOMT",38,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",39,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",40,0)
+ QUIT
+"RTN","MXMLDOMT",41,0)
+XML6 ; @TEST - Parse an XML doc with Chracter ref text broken over 2 lines (George's bug)
+"RTN","MXMLDOMT",42,0)
+ D READ("XML6D")
+"RTN","MXMLDOMT",43,0)
+ N D S D=$$EN^MXMLDOM($NA(^TMP($J)),"WD")
+"RTN","MXMLDOMT",44,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",45,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",46,0)
+ QUIT
+"RTN","MXMLDOMT",47,0)
+XMLFILE ; @TEST - Parse an XML document loacated on the File system (Sam's bug)
+"RTN","MXMLDOMT",48,0)
+ D READ("XML1D")
+"RTN","MXMLDOMT",49,0)
+ ;
+"RTN","MXMLDOMT",50,0)
+ ; Write file
+"RTN","MXMLDOMT",51,0)
+ N % S %=$$GTF^%ZISH($NA(^TMP($J,1)),2,$$DEFDIR^%ZISH(),"mxmldomt.xml")
+"RTN","MXMLDOMT",52,0)
+ I '% S $EC=",U-FILE-WRITE-FAIL,"
+"RTN","MXMLDOMT",53,0)
+ ;
+"RTN","MXMLDOMT",54,0)
+ ; Check 1: No path supplied. System supposed to use default directory
+"RTN","MXMLDOMT",55,0)
+ N D S D=$$EN^MXMLDOM("mxmldomt.xml","WD")
+"RTN","MXMLDOMT",56,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",57,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",58,0)
+ ;
+"RTN","MXMLDOMT",59,0)
+ ; Check 2; Supply path explicitly
+"RTN","MXMLDOMT",60,0)
+ N D S D=$$EN^MXMLDOM($$DEFDIR^%ZISH()_"mxmldomt.xml","WD")
+"RTN","MXMLDOMT",61,0)
+ D CHKTF^%ut(D,"XML not parsed")
+"RTN","MXMLDOMT",62,0)
+ D DELETE^MXMLDOM(D)
+"RTN","MXMLDOMT",63,0)
+ ;
+"RTN","MXMLDOMT",64,0)
+ ; Delete file
+"RTN","MXMLDOMT",65,0)
+ N %1 S %1("mxmldomt.xml")=""
+"RTN","MXMLDOMT",66,0)
+ S %=$$DEL^%ZISH($$DEFDIR^%ZISH(),$NA(%1))
+"RTN","MXMLDOMT",67,0)
+ QUIT
+"RTN","MXMLDOMT",68,0)
+XML136 ; @TEST - VA Patch 136 - Long comments are not read properly
+"RTN","MXMLDOMT",69,0)
+ N CB,I,TEST,Y,Z
+"RTN","MXMLDOMT",70,0)
+ K ^TMP($J,"P136 TEST")
+"RTN","MXMLDOMT",71,0)
+ S U="^",TEST="FAILED",Z=0
+"RTN","MXMLDOMT",72,0)
+ F I=1:1 S Y=$T(XML7D+I) Q:Y="" D
+"RTN","MXMLDOMT",73,0)
+ .I $E(Y,1,3)=" ;;" S Y=$E(Y,4,999),Z=Z+1,^TMP($J,"P136 TEST",Z)=Y Q
+"RTN","MXMLDOMT",74,0)
+ .S Y=$E(Y,2,999),^TMP($J,"P136 TEST",Z)=^TMP($J,"P136 TEST",Z)_Y
+"RTN","MXMLDOMT",75,0)
+ .Q
+"RTN","MXMLDOMT",76,0)
+ S CB("ENDDOCUMENT")="ENDD^MXMLDOMT",Y="^TMP($J,""P136 TEST"")"
+"RTN","MXMLDOMT",77,0)
+ D EN^MXMLPRSE(Y,.CB,"")
+"RTN","MXMLDOMT",78,0)
+ D CHKEQ^%ut(TEST,"PASSED","Long comments are not parsed properly")
+"RTN","MXMLDOMT",79,0)
+ K ^TMP($J,"P136 TEST")
+"RTN","MXMLDOMT",80,0)
+ Q
+"RTN","MXMLDOMT",81,0)
+ENDD ;end of document call back
+"RTN","MXMLDOMT",82,0)
+ ;ZEXCEPT: TEST
+"RTN","MXMLDOMT",83,0)
+ S TEST="PASSED"
+"RTN","MXMLDOMT",84,0)
+ Q
+"RTN","MXMLDOMT",85,0)
+READ(TAGNAME) ; Read XML from tag
+"RTN","MXMLDOMT",86,0)
+ K ^TMP($J)
+"RTN","MXMLDOMT",87,0)
+ N LN
+"RTN","MXMLDOMT",88,0)
+ N I F I=1:1 S LN=$P($T(@TAGNAME+I),";;",2) Q:'$L(LN) S ^TMP($J,I)=LN
+"RTN","MXMLDOMT",89,0)
+ QUIT
+"RTN","MXMLDOMT",90,0)
+ ;
+"RTN","MXMLDOMT",91,0)
+XML1D ;; @DATA for Test 1
+"RTN","MXMLDOMT",92,0)
+ ;;
+"RTN","MXMLDOMT",93,0)
+ ;;
+"RTN","MXMLDOMT",94,0)
+ ;;
+"RTN","MXMLDOMT",95,0)
+ ;;Tove
+"RTN","MXMLDOMT",96,0)
+ ;;Jani
+"RTN","MXMLDOMT",97,0)
+ ;;Reminder
+"RTN","MXMLDOMT",98,0)
+ ;;Don't forget me this weekend!
+"RTN","MXMLDOMT",99,0)
+ ;;
+"RTN","MXMLDOMT",100,0)
+ ;;
+"RTN","MXMLDOMT",101,0)
+XML2D ;; @DATA for Test 2
+"RTN","MXMLDOMT",102,0)
+ ;;ToveJaniReminderDon't forget me this weekend!
+"RTN","MXMLDOMT",103,0)
+ ;;
+"RTN","MXMLDOMT",104,0)
+XML3D ;; @DATA for Test 3
+"RTN","MXMLDOMT",105,0)
+ ;;
+"RTN","MXMLDOMT",107,0)
+ ;;
+"RTN","MXMLDOMT",109,0)
+ ;;
+"RTN","MXMLDOMT",111,0)
+ ;;Tove<
+"RTN","MXMLDOMT",112,0)
+ ;;/to>
+"RTN","MXMLDOMT",113,0)
+ ;;Jani
+"RTN","MXMLDOMT",114,0)
+ ;;Reminder
+"RTN","MXMLDOMT",115,0)
+ ;;Don't forget me this weekend!
+"RTN","MXMLDOMT",116,0)
+ ;;body>
+"RTN","MXMLDOMT",117,0)
+ ;;
+"RTN","MXMLDOMT",118,0)
+ ;;
+"RTN","MXMLDOMT",119,0)
+XML4D ;; @DATA for Test 4
+"RTN","MXMLDOMT",120,0)
+ ;;
+"RTN","MXMLDOMT",121,0)
+ ;;
+"RTN","MXMLDOMT",122,0)
+ ;;
+"RTN","MXMLDOMT",123,0)
+ ;;Tove
+"RTN","MXMLDOMT",124,0)
+ ;;Jani
+"RTN","MXMLDOMT",125,0)
+ ;;Reminder
+"RTN","MXMLDOMT",126,0)
+ ;;Don't forget me this weekend!
+"RTN","MXMLDOMT",127,0)
+ ;;
+"RTN","MXMLDOMT",128,0)
+ ;;
+"RTN","MXMLDOMT",129,0)
+XML5D ;; @DATA for Test 5 (Sergey's bug!)
+"RTN","MXMLDOMT",130,0)
+ ;;
+"RTN","MXMLDOMT",131,0)
+ ;;
+"RTN","MXMLDOMT",132,0)
+ ;;
+"RTN","MXMLDOMT",133,0)
+ ;;
+"RTN","MXMLDOMT",134,0)
+ ;;AAAAAAAAAAAAAAAAAAAAAAAAAAAATove
+"RTN","MXMLDOMT",138,0)
+ ;;Jani
+"RTN","MXMLDOMT",139,0)
+ ;;Reminder
+"RTN","MXMLDOMT",140,0)
+ ;;Don't forget me this weekend!
+"RTN","MXMLDOMT",141,0)
+ ;;
+"RTN","MXMLDOMT",142,0)
+ ;;
+"RTN","MXMLDOMT",143,0)
+XML6D ;; @DATA for Test 6 (George's bug!)
+"RTN","MXMLDOMT",144,0)
+ ;;
+"RTN","MXMLDOMT",145,0)
+ ;;
+"RTN","MXMLDOMT",146,0)
+ ;;
+"RTN","MXMLDOMT",147,0)
+ ;;
+"RTN","MXMLDOMT",148,0)
+ ;;AAAAAAAAAAAAAAAAAAAAAAAAAAAA
+"RTN","MXMLDOMT",149,0)
+ ;;Toveüüüüüüüüüüüüü
+"RTN","MXMLDOMT",150,0)
+ ;;xfc;üüüüüüüü&
+"RTN","MXMLDOMT",151,0)
+ ;;#xfc;üüüüüüüü
+"RTN","MXMLDOMT",152,0)
+ ;;c;üüüüüüü
+"RTN","MXMLDOMT",153,0)
+ ;;Jani
+"RTN","MXMLDOMT",154,0)
+ ;;Reminder
+"RTN","MXMLDOMT",155,0)
+ ;;Don't forget me this weekend!
+"RTN","MXMLDOMT",156,0)
+ ;;
+"RTN","MXMLDOMT",157,0)
+ ;;
+"RTN","MXMLDOMT",158,0)
+XML7D ;; @DATA for Test 7 (VA patch 136)
+"RTN","MXMLDOMT",159,0)
+ ;;
+"RTN","MXMLDOMT",160,0)
+ ;;
+"RTN","MXMLDOMT",169,0)
+ ;;
+"RTN","MXMLPATH")
+0^7^B98631514
+"RTN","MXMLPATH",1,0)
+MXMLPATH ; VEN/SMH - XPATH Extensions to MXML Package ;2015-05-25 11:37 AM
+"RTN","MXMLPATH",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;June 15, 2015;Build 14
+"RTN","MXMLPATH",3,0)
+ ;
+"RTN","MXMLPATH",4,0)
+ ; (c) Sam Habiel 2014
+"RTN","MXMLPATH",5,0)
+ ;
+"RTN","MXMLPATH",6,0)
+ ; Public Entry Point: [$$]XPATH. The rest is private.
+"RTN","MXMLPATH",7,0)
+ ;
+"RTN","MXMLPATH",8,0)
+ ; TODO:
+"RTN","MXMLPATH",9,0)
+ ; - Handle /a/*
+"RTN","MXMLPATH",10,0)
+ ; - Handle /a/[]
+"RTN","MXMLPATH",11,0)
+ ; - Handle /a//b
+"RTN","MXMLPATH",12,0)
+ ; - Handle . and ..
+"RTN","MXMLPATH",13,0)
+ ;
+"RTN","MXMLPATH",14,0)
+XPATH(RETURN,DOCHAND,XPATH) ; Public Entry Point - XPATH Processor
+"RTN","MXMLPATH",15,0)
+ ; Input:
+"RTN","MXMLPATH",16,0)
+ ; - .RETURN - Return array. Returns nodes where the XPATH found data. (Reference)
+"RTN","MXMLPATH",17,0)
+ ; ---> E.g. RETURN(8)=""
+"RTN","MXMLPATH",18,0)
+ ; ---> RETURN(15)=""
+"RTN","MXMLPATH",19,0)
+ ; - DOCHAND - The MXMLDOM Document Handle (Value)
+"RTN","MXMLPATH",20,0)
+ ; - XPATH - XPATH Expression (Value)
+"RTN","MXMLPATH",21,0)
+ ;
+"RTN","MXMLPATH",22,0)
+ ; If $$, return first found node; or first attribute value if attribute requested.
+"RTN","MXMLPATH",23,0)
+ ;
+"RTN","MXMLPATH",24,0)
+ KILL RETURN
+"RTN","MXMLPATH",25,0)
+ ;
+"RTN","MXMLPATH",26,0)
+ ; Handle / all by itself. Return 1.
+"RTN","MXMLPATH",27,0)
+ IF XPATH="/" DO QUIT:$QUIT $$QUITVAL(.RETURN) QUIT
+"RTN","MXMLPATH",28,0)
+ . SET RETURN(1)=""
+"RTN","MXMLPATH",29,0)
+ . SET ^TMP("MXMLDOM",$JOB,DOCHAND,"CURRENT-NODE")=1
+"RTN","MXMLPATH",30,0)
+ ;
+"RTN","MXMLPATH",31,0)
+ ; Handle //a/b/c/d ; find a/b/c/d anywhere in the document.
+"RTN","MXMLPATH",32,0)
+ IF $EXTRACT(XPATH,1,2)="//" DO QUIT:$QUIT $$QUITVAL(.RETURN) QUIT ; find element anywhere in the document
+"RTN","MXMLPATH",33,0)
+ . SET XPATH=$EXTRACT(XPATH,3,999) ; Strip off the //
+"RTN","MXMLPATH",34,0)
+ . IF XPATH="" SET $ECODE=",U-INVALID-XPATH," ; // by itself is invalid
+"RTN","MXMLPATH",35,0)
+ . DO SS(.RETURN,DOCHAND,XPATH) ; find all nodes with the rest of the path (no parents; i.e. look anywhere)
+"RTN","MXMLPATH",36,0)
+ . SET ^TMP("MXMLDOM",$JOB,DOCHAND,"CURRENT-NODE")=$ORDER(RETURN(""),-1)
+"RTN","MXMLPATH",37,0)
+ ;
+"RTN","MXMLPATH",38,0)
+ ;
+"RTN","MXMLPATH",39,0)
+ ; Handle /a/b/c/d ; find /a/b/c/d starting from the root.
+"RTN","MXMLPATH",40,0)
+ IF $EXTRACT(XPATH)="/" DO QUIT:$QUIT $$QUITVAL(.RETURN) QUIT
+"RTN","MXMLPATH",41,0)
+ . ;
+"RTN","MXMLPATH",42,0)
+ . ; Make sure that the document root is "a"
+"RTN","MXMLPATH",43,0)
+ . SET XPATH=$EXTRACT(XPATH,2,999)
+"RTN","MXMLPATH",44,0)
+ . NEW H SET H=$PIECE(XPATH,"/")
+"RTN","MXMLPATH",45,0)
+ . IF ^TMP("MXMLDOM",$JOB,DOCHAND,1)'=H QUIT
+"RTN","MXMLPATH",46,0)
+ . SET XPATH=$PIECE(XPATH,"/",2,99) ; we change this now to a relative path from the root node.
+"RTN","MXMLPATH",47,0)
+ . ;
+"RTN","MXMLPATH",48,0)
+ . ; Pass in the root node as the parent
+"RTN","MXMLPATH",49,0)
+ . NEW PARENTS SET PARENTS(1)=""
+"RTN","MXMLPATH",50,0)
+ . DO SS(.RETURN,DOCHAND,XPATH,.PARENTS)
+"RTN","MXMLPATH",51,0)
+ . SET ^TMP("MXMLDOM",$JOB,DOCHAND,"CURRENT-NODE")=$ORDER(RETURN(""),-1)
+"RTN","MXMLPATH",52,0)
+ ;
+"RTN","MXMLPATH",53,0)
+ ; We have a relative path
+"RTN","MXMLPATH",54,0)
+ DO QUIT:$QUIT $$QUITVAL(.RETURN) QUIT
+"RTN","MXMLPATH",55,0)
+ . NEW CURRNODE SET CURRNODE=$GET(^TMP("MXMLDOM",$JOB,DOCHAND,"CURRENT-NODE"),1)
+"RTN","MXMLPATH",56,0)
+ . NEW PARENTS SET PARENTS(CURRNODE)=""
+"RTN","MXMLPATH",57,0)
+ . DO SS(.RETURN,DOCHAND,XPATH,.PARENTS)
+"RTN","MXMLPATH",58,0)
+ . SET ^TMP("MXMLDOM",$JOB,DOCHAND,"CURRENT-NODE")=$ORDER(RETURN(""),-1)
+"RTN","MXMLPATH",59,0)
+ ;
+"RTN","MXMLPATH",60,0)
+ ; IF NEITHER OF THESE FORMATS, FAIL WITH NOT-IMPLEMENTED EXCEPTION.
+"RTN","MXMLPATH",61,0)
+ SET $ECODE=",UUNIMPLEMENTED,"
+"RTN","MXMLPATH",62,0)
+ ;
+"RTN","MXMLPATH",63,0)
+ QUIT:$QUIT "" QUIT ; We won't hit this; but for future use
+"RTN","MXMLPATH",64,0)
+ ;
+"RTN","MXMLPATH",65,0)
+QUITVAL(RETURN) ; $$/Private - What is the quit value? ; Input .RETURN.
+"RTN","MXMLPATH",66,0)
+ NEW N1 SET N1=$ORDER(RETURN("")) ;first node
+"RTN","MXMLPATH",67,0)
+ IF N1="" QUIT "" ; No results found.
+"RTN","MXMLPATH",68,0)
+ IF $DATA(RETURN(N1))=10 NEW N2 SET N2=$ORDER(RETURN(N1,"")) QUIT RETURN(N1,N2) ; VALUE of first found attribute
+"RTN","MXMLPATH",69,0)
+ ELSE QUIT N1 ; first found node
+"RTN","MXMLPATH",70,0)
+ ;
+"RTN","MXMLPATH",71,0)
+SS(RETURN,DOCHAND,XPATH,PARENTS) ; Private; Main search code
+"RTN","MXMLPATH",72,0)
+ ; .RETURN -> Return array to be populated
+"RTN","MXMLPATH",73,0)
+ ; DOCHAND -> MXMLDOM Handle
+"RTN","MXMLPATH",74,0)
+ ; XPATH -> XPATH to search
+"RTN","MXMLPATH",75,0)
+ ; .PARENTS -> XML Parent nodes already identified
+"RTN","MXMLPATH",76,0)
+ ; Don't pass if you want to search anywhere in the document.
+"RTN","MXMLPATH",77,0)
+ ; Pass PARENTS(NODEID)="" if you want to limit searching to below
+"RTN","MXMLPATH",78,0)
+ ; ...these node(s).
+"RTN","MXMLPATH",79,0)
+ ;
+"RTN","MXMLPATH",80,0)
+ NEW SURPARENTS MERGE SURPARENTS=PARENTS ; Surviving parents
+"RTN","MXMLPATH",81,0)
+ ;
+"RTN","MXMLPATH",82,0)
+ ; Now, recurse over the rest of the XPATH expression
+"RTN","MXMLPATH",83,0)
+ NEW XPATHL SET XPATHL=$LENGTH(XPATH,"/") ; # of pieces
+"RTN","MXMLPATH",84,0)
+ NEW QUITFLAG SET QUITFLAG=0
+"RTN","MXMLPATH",85,0)
+ NEW I FOR I=1:1:XPATHL DO QUIT:'$DATA(SURPARENTS) QUIT:QUITFLAG
+"RTN","MXMLPATH",86,0)
+ . NEW CHILD SET CHILD=$PIECE(XPATH,"/",I) ; XPATH piece
+"RTN","MXMLPATH",87,0)
+ . ;
+"RTN","MXMLPATH",88,0)
+ . ; make sure that each piece is at least 1 character long
+"RTN","MXMLPATH",89,0)
+ . IF CHILD="",I=XPATHL SET $ECODE=",U-INVALID-XPATH," ; error if the user give us something with a trailing slash. (a/b/c/)
+"RTN","MXMLPATH",90,0)
+ . ELSE ; this is the abc//def case. TODO.
+"RTN","MXMLPATH",91,0)
+ . ;
+"RTN","MXMLPATH",92,0)
+ . IF $EXTRACT(CHILD)="@" DO SET QUITFLAG=1 QUIT ; Attribute requested...
+"RTN","MXMLPATH",93,0)
+ . . ; SURPARENTS will only be empty if we have the special case of //@attribute
+"RTN","MXMLPATH",94,0)
+ . . IF '$DATA(SURPARENTS) DO ALLNODES(.SURPARENTS,DOCHAND) ; This is really confusing!!!!
+"RTN","MXMLPATH",95,0)
+ . . DO ATTRIB(DOCHAND,CHILD,.SURPARENTS)
+"RTN","MXMLPATH",96,0)
+ . ;
+"RTN","MXMLPATH",97,0)
+ . NEW FILTER SET FILTER=""
+"RTN","MXMLPATH",98,0)
+ . IF $EXTRACT(CHILD,$LENGTH(CHILD))="]" DO ; The child has a condition on it.
+"RTN","MXMLPATH",99,0)
+ . . SET FILTER=$PIECE(CHILD,"[",2),FILTER=$PIECE(FILTER,"]") ; get contents of [...]
+"RTN","MXMLPATH",100,0)
+ . . SET CHILD=$PIECE(CHILD,"[") ; strip [...]
+"RTN","MXMLPATH",101,0)
+ . ;
+"RTN","MXMLPATH",102,0)
+ . ; Handle . and ..
+"RTN","MXMLPATH",103,0)
+ . ; IF $E(CHILD)="." D
+"RTN","MXMLPATH",104,0)
+ . ; . I CHILD="." S:$O(SURPARENTS("")) CNODES($O(SURPARENTS(""),-1))="" ; Set to the last found parent
+"RTN","MXMLPATH",105,0)
+ . ; . I CHILD=".." S CNODES(PARENT^MXMLDOM(DOCHAND,SURPARENTS)) ; TODO: Loop through parents and move up.
+"RTN","MXMLPATH",106,0)
+ . ;
+"RTN","MXMLPATH",107,0)
+ . NEW CNODES DO SEARCHNO(.CNODES,DOCHAND,CHILD) ; Grab child nodes from XML doc.
+"RTN","MXMLPATH",108,0)
+ . IF '$DATA(CNODES) KILL SURPARENTS QUIT ; XPATH expr yielded no results.
+"RTN","MXMLPATH",109,0)
+ . ;
+"RTN","MXMLPATH",110,0)
+ . ; Now make sure that the children nodes are indeed children of the parents.
+"RTN","MXMLPATH",111,0)
+ . N SURCHILDREN ; Surviving Children
+"RTN","MXMLPATH",112,0)
+ . DO WEEDOUT(.SURCHILDREN,.SURPARENTS,.CNODES,DOCHAND) ; only run if we have parents (not first node in //)
+"RTN","MXMLPATH",113,0)
+ .
+"RTN","MXMLPATH",114,0)
+ . ; Any children left?
+"RTN","MXMLPATH",115,0)
+ . IF '$DATA(SURCHILDREN) KILL SURPARENTS QUIT ; XPATH expr yielded no results.
+"RTN","MXMLPATH",116,0)
+ . ;
+"RTN","MXMLPATH",117,0)
+ . DO:$LENGTH(FILTER) FILTER(DOCHAND,.SURCHILDREN,FILTER) ; Apply filter expression
+"RTN","MXMLPATH",118,0)
+ . ;
+"RTN","MXMLPATH",119,0)
+ . ; DO DEBUG(.SURCHILDREN,DOCHAND)
+"RTN","MXMLPATH",120,0)
+ . ;
+"RTN","MXMLPATH",121,0)
+ . ; Any children left?
+"RTN","MXMLPATH",122,0)
+ . IF '$DATA(SURCHILDREN) KILL SURPARENTS QUIT ; XPATH expr yielded no results.
+"RTN","MXMLPATH",123,0)
+ . ;
+"RTN","MXMLPATH",124,0)
+ . ; The children are now the new parents
+"RTN","MXMLPATH",125,0)
+ . KILL SURPARENTS MERGE SURPARENTS=SURCHILDREN
+"RTN","MXMLPATH",126,0)
+ ;
+"RTN","MXMLPATH",127,0)
+ MERGE RETURN=SURPARENTS ; The surviving parents are the return value
+"RTN","MXMLPATH",128,0)
+ QUIT
+"RTN","MXMLPATH",129,0)
+ ;
+"RTN","MXMLPATH",130,0)
+WEEDOUT(SURVIVORS,PARENTS,CHILDREN,DOCHAND) ; Remove bastard child nodes
+"RTN","MXMLPATH",131,0)
+ ; Input: .PARENTS AND .CHILDREN - node subscripted arrays
+"RTN","MXMLPATH",132,0)
+ ; Output: .SURVIVORS
+"RTN","MXMLPATH",133,0)
+ ; DOCHAND ditto
+"RTN","MXMLPATH",134,0)
+ ;
+"RTN","MXMLPATH",135,0)
+ ; No parents? Children are survivors
+"RTN","MXMLPATH",136,0)
+ I '$D(PARENTS) M SURVIVORS=CHILDREN QUIT
+"RTN","MXMLPATH",137,0)
+ ;
+"RTN","MXMLPATH",138,0)
+ NEW P SET P=0 FOR SET P=$ORDER(PARENTS(P)) QUIT:'P D
+"RTN","MXMLPATH",139,0)
+ . ;NEW C SET C=0 FOR SET C=$ORDER(CHILDREN(C)) QUIT:'C D
+"RTN","MXMLPATH",140,0)
+ . NEW C SET C=0 FOR SET C=$ORDER(^TMP("MXMLDOM",$JOB,DOCHAND,P,"C",C)) QUIT:'C D
+"RTN","MXMLPATH",141,0)
+ . . I $D(CHILDREN(C)) S SURVIVORS(C)=""
+"RTN","MXMLPATH",142,0)
+ QUIT
+"RTN","MXMLPATH",143,0)
+ ;
+"RTN","MXMLPATH",144,0)
+SEARCHNO(RETURN,DOCHAND,NODENAME) ; Simple linear search of nodes on MXML document
+"RTN","MXMLPATH",145,0)
+ ; Find nodes in document called NODENAME and return in RETURN.
+"RTN","MXMLPATH",146,0)
+ ; .RETURN,DOCHAND - ditto; NODENAME - string name of element node.
+"RTN","MXMLPATH",147,0)
+ NEW I SET I=0
+"RTN","MXMLPATH",148,0)
+ FOR SET I=$ORDER(^TMP("MXMLDOM",$JOB,DOCHAND,I)) QUIT:'I SET:^(I)=NODENAME RETURN(I)=""
+"RTN","MXMLPATH",149,0)
+ QUIT
+"RTN","MXMLPATH",150,0)
+ ;
+"RTN","MXMLPATH",151,0)
+ALLNODES(RETURN,DOCHAND) ; Return all XML element nodes in DOM.
+"RTN","MXMLPATH",152,0)
+ NEW I SET I=0 FOR SET I=$ORDER(^TMP("MXMLDOM",$JOB,DOCHAND,I)) QUIT:'I SET RETURN(I)=""
+"RTN","MXMLPATH",153,0)
+ QUIT
+"RTN","MXMLPATH",154,0)
+ ;
+"RTN","MXMLPATH",155,0)
+ISCHILD(PARENT,CHILD,DOCHAND) ; Is node CHILD (int) a child of node PARENT (int)?
+"RTN","MXMLPATH",156,0)
+ QUIT $DATA(^TMP("MXMLDOM",$JOB,DOCHAND,PARENT,"C",CHILD))
+"RTN","MXMLPATH",157,0)
+ ;
+"RTN","MXMLPATH",158,0)
+TEXTFIL(DOCHAND,NODES,TEXT) ; Text filter though the nodes
+"RTN","MXMLPATH",159,0)
+ ; Search the .NODES in MXMLDOM document DOCHAND for TEXT.
+"RTN","MXMLPATH",160,0)
+ NEW I SET I=0 FOR SET I=$ORDER(NODES(I)) QUIT:'I DO
+"RTN","MXMLPATH",161,0)
+ . IF ^TMP("MXMLDOM",$JOB,DOCHAND,I,"T",1)'=TEXT KILL NODES(I)
+"RTN","MXMLPATH",162,0)
+ QUIT
+"RTN","MXMLPATH",163,0)
+ ;
+"RTN","MXMLPATH",164,0)
+ATTRIB(DOCHAND,ATTRIB,NODES) ; Get ATTRIB attribute from each of the NODES
+"RTN","MXMLPATH",165,0)
+ ; Change NODES(n) array to NODES(n,ATTNAME)=VALUE array
+"RTN","MXMLPATH",166,0)
+ ; DOCHAND, ditto; ATTRIB - attribute string; NODES - subscripted array of
+"RTN","MXMLPATH",167,0)
+ ; MXMLDOM nodes
+"RTN","MXMLPATH",168,0)
+ SET ATTRIB=$PIECE(ATTRIB,"@",2,99) ; Strip the @.
+"RTN","MXMLPATH",169,0)
+ NEW I SET I="" FOR SET I=$ORDER(NODES(I)) QUIT:'I DO
+"RTN","MXMLPATH",170,0)
+ . NEW V SET V=$$VALUE^MXMLDOM(DOCHAND,I,ATTRIB)
+"RTN","MXMLPATH",171,0)
+ . IF V="" KILL NODES(I)
+"RTN","MXMLPATH",172,0)
+ . ELSE KILL NODES(I) SET NODES(I,ATTRIB)=V
+"RTN","MXMLPATH",173,0)
+ QUIT
+"RTN","MXMLPATH",174,0)
+ ;
+"RTN","MXMLPATH",175,0)
+FILTER(DOCHAND,NODES,FILTER) ; process [...] filter on xpath results
+"RTN","MXMLPATH",176,0)
+ ; INPUT:
+"RTN","MXMLPATH",177,0)
+ ; - DOCHAND, NODES: ditto
+"RTN","MXMLPATH",178,0)
+ ; - NODES is both INPUT and OUTPUT, as it is the array being filtered.
+"RTN","MXMLPATH",179,0)
+ ; - FILTER: filter string without the [].
+"RTN","MXMLPATH",180,0)
+ ;
+"RTN","MXMLPATH",181,0)
+ ; supports only the following filter expressions right now:
+"RTN","MXMLPATH",182,0)
+ ; - position(n)
+"RTN","MXMLPATH",183,0)
+ ; - n
+"RTN","MXMLPATH",184,0)
+ ; - last()
+"RTN","MXMLPATH",185,0)
+ ; - @att
+"RTN","MXMLPATH",186,0)
+ ; - @att="foo"
+"RTN","MXMLPATH",187,0)
+ ; - node
+"RTN","MXMLPATH",188,0)
+ ; - node="foo"
+"RTN","MXMLPATH",189,0)
+ ;
+"RTN","MXMLPATH",190,0)
+ QUIT:'$DATA(NODES)
+"RTN","MXMLPATH",191,0)
+ ;
+"RTN","MXMLPATH",192,0)
+ ; position(n)? convert to number.
+"RTN","MXMLPATH",193,0)
+ IF FILTER["position(" SET FILTER=$PIECE(FILTER,"position(",2),FILTER=$PIECE(FILTER,")")
+"RTN","MXMLPATH",194,0)
+ ;
+"RTN","MXMLPATH",195,0)
+ ; Number? Kill all nodes not in that ordinal position and done.
+"RTN","MXMLPATH",196,0)
+ IF +FILTER=FILTER DO QUIT
+"RTN","MXMLPATH",197,0)
+ . NEW CNT SET CNT=0
+"RTN","MXMLPATH",198,0)
+ . NEW I SET I=0 FOR SET I=$ORDER(NODES(I)) QUIT:'I DO
+"RTN","MXMLPATH",199,0)
+ . . SET CNT=CNT+1
+"RTN","MXMLPATH",200,0)
+ . . IF CNT'=FILTER KILL NODES(I)
+"RTN","MXMLPATH",201,0)
+ ;
+"RTN","MXMLPATH",202,0)
+ ; last()? Grab that and done.
+"RTN","MXMLPATH",203,0)
+ IF FILTER="last()" DO QUIT
+"RTN","MXMLPATH",204,0)
+ . NEW LAST SET LAST=$ORDER(NODES(""),-1)
+"RTN","MXMLPATH",205,0)
+ . NEW VAL SET VAL=NODES(LAST)
+"RTN","MXMLPATH",206,0)
+ . KILL NODES
+"RTN","MXMLPATH",207,0)
+ . SET NODES(LAST)=VAL
+"RTN","MXMLPATH",208,0)
+ ;
+"RTN","MXMLPATH",209,0)
+ ;
+"RTN","MXMLPATH",210,0)
+ ; No = sign. Either @attribute or node
+"RTN","MXMLPATH",211,0)
+ IF $LENGTH(FILTER,"=")=1 DO QUIT
+"RTN","MXMLPATH",212,0)
+ . IF $EXTRACT(FILTER)="@" DO QUIT ; attribute
+"RTN","MXMLPATH",213,0)
+ . . NEW ATTRIB SET ATTRIB=FILTER
+"RTN","MXMLPATH",214,0)
+ . . DO ATTRIB(DOCHAND,ATTRIB,.NODES) ; filter by attribute
+"RTN","MXMLPATH",215,0)
+ . . ; Re-align the nodes as we don't care about attrib contents.
+"RTN","MXMLPATH",216,0)
+ . . ; (i.e. discard the return value of ATTRIB call and return nodes back
+"RTN","MXMLPATH",217,0)
+ . . ; (to original NODES(n) form).
+"RTN","MXMLPATH",218,0)
+ . . NEW I SET I=0 FOR SET I=$ORDER(NODES(I)) QUIT:'I SET NODES(I)="" KILL NODES(I,$PIECE(ATTRIB,"@",2))
+"RTN","MXMLPATH",219,0)
+ . ;
+"RTN","MXMLPATH",220,0)
+ . ELSE DO QUIT ; node
+"RTN","MXMLPATH",221,0)
+ . . NEW CHILDNAME SET CHILDNAME=FILTER ; node name is same as FILTER
+"RTN","MXMLPATH",222,0)
+ . . ;
+"RTN","MXMLPATH",223,0)
+ . . ; Get all nodes with that filter name
+"RTN","MXMLPATH",224,0)
+ . . NEW CHILDREN DO SEARCHNO(.CHILDREN,DOCHAND,CHILDNAME)
+"RTN","MXMLPATH",225,0)
+ . . IF '$DATA(CHILDREN) KILL NODES QUIT ; no children
+"RTN","MXMLPATH",226,0)
+ . . ;
+"RTN","MXMLPATH",227,0)
+ . . ; Remove all the filter nodes who are not directly under us
+"RTN","MXMLPATH",228,0)
+ . . ; Store result in PARENTS(n)=""
+"RTN","MXMLPATH",229,0)
+ . . NEW PARENTS
+"RTN","MXMLPATH",230,0)
+ . . NEW I SET I=0 FOR SET I=$ORDER(NODES(I)) QUIT:'I NEW J SET J=0 FOR SET J=$ORDER(CHILDREN(J)) QUIT:'J DO
+"RTN","MXMLPATH",231,0)
+ . . . IF $$ISCHILD(I,J,DOCHAND) SET PARENTS(I)=""
+"RTN","MXMLPATH",232,0)
+ . . ;
+"RTN","MXMLPATH",233,0)
+ . . ; Kill the original return array and recreate it from PARENTS
+"RTN","MXMLPATH",234,0)
+ . . KILL NODES
+"RTN","MXMLPATH",235,0)
+ . . MERGE NODES=PARENTS
+"RTN","MXMLPATH",236,0)
+ . . KILL PARENTS
+"RTN","MXMLPATH",237,0)
+ ;
+"RTN","MXMLPATH",238,0)
+ ; attribute @attribute="value"
+"RTN","MXMLPATH",239,0)
+ IF $EXTRACT(FILTER)="@" DO QUIT
+"RTN","MXMLPATH",240,0)
+ . NEW ATTRIB SET ATTRIB=$PIECE(FILTER,"=")
+"RTN","MXMLPATH",241,0)
+ . DO ATTRIB(DOCHAND,ATTRIB,.NODES) ; Grab nodes that have this attribute
+"RTN","MXMLPATH",242,0)
+ . NEW V SET V=$PIECE(FILTER,"=",2),V=$PIECE(V,"""",2),V=$PIECE(V,"""") ; get value, rm quotes
+"RTN","MXMLPATH",243,0)
+ . ;
+"RTN","MXMLPATH",244,0)
+ . ; Filter out nodes whose attribute value doesn't match.
+"RTN","MXMLPATH",245,0)
+ . NEW I SET I=0 FOR SET I=$ORDER(NODES(I)) QUIT:'I DO
+"RTN","MXMLPATH",246,0)
+ . . IF NODES(I,$PIECE(ATTRIB,"@",2))'=V KILL NODES(I)
+"RTN","MXMLPATH",247,0)
+ . . ELSE SET NODES(I)="" KILL NODES(I,$PIECE(ATTRIB,"@",2))
+"RTN","MXMLPATH",248,0)
+ ;
+"RTN","MXMLPATH",249,0)
+ ; NODE node="value"
+"RTN","MXMLPATH",250,0)
+ ELSE DO QUIT
+"RTN","MXMLPATH",251,0)
+ . NEW CHILDNAME SET CHILDNAME=$PIECE(FILTER,"=")
+"RTN","MXMLPATH",252,0)
+ . NEW CHILDREN DO SEARCHNO(.CHILDREN,DOCHAND,CHILDNAME) ; Grab nodes with this value
+"RTN","MXMLPATH",253,0)
+ . NEW V SET V=$PIECE(FILTER,"=",2),V=$PIECE(V,"""",2),V=$PIECE(V,"""") ; get value, rm quotes
+"RTN","MXMLPATH",254,0)
+ . ;
+"RTN","MXMLPATH",255,0)
+ . ; Remote nodes whose text contents are not the filter value.
+"RTN","MXMLPATH",256,0)
+ . DO TEXTFIL(DOCHAND,.CHILDREN,V)
+"RTN","MXMLPATH",257,0)
+ . IF '$DATA(CHILDREN) KILL NODES QUIT
+"RTN","MXMLPATH",258,0)
+ . ;
+"RTN","MXMLPATH",259,0)
+ . ; Remove all filter nodes not directly under us.
+"RTN","MXMLPATH",260,0)
+ . ; Store result in PARENTS(n)=""
+"RTN","MXMLPATH",261,0)
+ . NEW PARENTS
+"RTN","MXMLPATH",262,0)
+ . NEW I SET I=0 FOR SET I=$ORDER(NODES(I)) QUIT:'I NEW J SET J=0 FOR SET J=$ORDER(CHILDREN(J)) QUIT:'J DO
+"RTN","MXMLPATH",263,0)
+ . . IF $$ISCHILD(I,J,DOCHAND) SET PARENTS(I)=""
+"RTN","MXMLPATH",264,0)
+ . ;
+"RTN","MXMLPATH",265,0)
+ . ; Kill return value and replace it with PARENTS.
+"RTN","MXMLPATH",266,0)
+ . KILL NODES
+"RTN","MXMLPATH",267,0)
+ . MERGE NODES=PARENTS
+"RTN","MXMLPATH",268,0)
+ . KILL PARENTS
+"RTN","MXMLPATH",269,0)
+ ;
+"RTN","MXMLPATH",270,0)
+ QUIT
+"RTN","MXMLPATH",271,0)
+DEBUG(NODES,DOCHAND) ; Debug print; Just used internally for debugging.
+"RTN","MXMLPATH",272,0)
+ N C S C=0
+"RTN","MXMLPATH",273,0)
+ N N S N=0 F S N=$O(NODES(N)) Q:'N W N_": "_^TMP("MXMLDOM",$J,DOCHAND,N),! S C=C+1
+"RTN","MXMLPATH",274,0)
+ W "Count: "_C,!
+"RTN","MXMLPATH",275,0)
+ QUIT
+"RTN","MXMLPATT")
+0^8^B211415201
+"RTN","MXMLPATT",1,0)
+MXMLPATT ; VEN/SMH-OSEHRA/JPS - MXML XPath Processor Unit Tests;2015-06-11 04:00 PM
+"RTN","MXMLPATT",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;June 15, 2015;Build 14
+"RTN","MXMLPATT",3,0)
+ ; (c) Sam Habiel 2014
+"RTN","MXMLPATT",4,0)
+TEST ; M-Unit Entry point for Unit Testing
+"RTN","MXMLPATT",5,0)
+ SET IO=$PRINCIPAL
+"RTN","MXMLPATT",6,0)
+ NEW DIQUIET SET DIQUIET=1
+"RTN","MXMLPATT",7,0)
+ DO DT^DICRW
+"RTN","MXMLPATT",8,0)
+ DO:$LENGTH($TEXT(EN^%ut))&$L($T(^MXMLPATH)) EN^%ut($TEXT(+0),1)
+"RTN","MXMLPATT",9,0)
+ QUIT
+"RTN","MXMLPATT",10,0)
+ ;
+"RTN","MXMLPATT",11,0)
+STARTUP ; M-Unit start-up; Load XML Document
+"RTN","MXMLPATT",12,0)
+ KILL ^TMP($JOB) ; array where we will store it
+"RTN","MXMLPATT",13,0)
+ NEW L ; Line text
+"RTN","MXMLPATT",14,0)
+ ;
+"RTN","MXMLPATT",15,0)
+ ; Load document
+"RTN","MXMLPATT",16,0)
+ NEW I FOR I=1:1 SET L=$TEXT(TESTDATA+I) SET L=$PIECE(L,";;",2) QUIT:L="<>" QUIT:L="" SET ^TMP($JOB,I)=L
+"RTN","MXMLPATT",17,0)
+ ;
+"RTN","MXMLPATT",18,0)
+ ; Parse document
+"RTN","MXMLPATT",19,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",20,0)
+ SET DOCHAND=$$EN^MXMLDOM($NAME(^TMP($JOB)),"W")
+"RTN","MXMLPATT",21,0)
+ ;
+"RTN","MXMLPATT",22,0)
+ IF 'DOCHAND DO FAIL^%ut("Could not parse XML")
+"RTN","MXMLPATT",23,0)
+ ;
+"RTN","MXMLPATT",24,0)
+ KILL ^TMP($JOB)
+"RTN","MXMLPATT",25,0)
+ QUIT
+"RTN","MXMLPATT",26,0)
+SHUTDOWN ; M-Unit Shutdown ; Delete parsed XML document from memory
+"RTN","MXMLPATT",27,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",28,0)
+ DO DELETE^MXMLDOM(DOCHAND)
+"RTN","MXMLPATT",29,0)
+ KILL DOCHAND
+"RTN","MXMLPATT",30,0)
+ QUIT
+"RTN","MXMLPATT",31,0)
+ ;
+"RTN","MXMLPATT",32,0)
+TESTS1 ; @TEST - Test /PEPSResponse/Body/drugCheck/drugDrugChecks/drugDrugCheck/source [extant]
+"RTN","MXMLPATT",33,0)
+ NEW XPATH SET XPATH="/PEPSResponse/Body/drugCheck/drugDrugChecks/drugDrugCheck/source"
+"RTN","MXMLPATT",34,0)
+ ;
+"RTN","MXMLPATT",35,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",36,0)
+ NEW RTN
+"RTN","MXMLPATT",37,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",38,0)
+ NEW TEXT
+"RTN","MXMLPATT",39,0)
+ DO TEXT^MXMLDOM(DOCHAND,$ORDER(RTN("")),$NAME(TEXT))
+"RTN","MXMLPATT",40,0)
+ DO CHKEQ^%ut(TEXT(1),"FDB",XPATH_" expression failed")
+"RTN","MXMLPATT",41,0)
+ QUIT
+"RTN","MXMLPATT",42,0)
+ ;
+"RTN","MXMLPATT",43,0)
+TESTS2 ; @TEST - Test /PEPSResponse/drugCheck/drugDrugChecks/drugDrugCheck/source [n/a]
+"RTN","MXMLPATT",44,0)
+ NEW XPATH SET XPATH="/PEPSResponse/drugCheck/drugDrugChecks/drugDrugCheck/source"
+"RTN","MXMLPATT",45,0)
+ ;
+"RTN","MXMLPATT",46,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",47,0)
+ NEW RTN
+"RTN","MXMLPATT",48,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",49,0)
+ NEW NODE SET NODE=$ORDER(RTN(""))
+"RTN","MXMLPATT",50,0)
+ DO CHKEQ^%ut(NODE,"",XPATH_" shouldn't be found")
+"RTN","MXMLPATT",51,0)
+ QUIT
+"RTN","MXMLPATT",52,0)
+ ;
+"RTN","MXMLPATT",53,0)
+TESTS3 ; @TEST - Test a multiple /PEPSResponse/.../reference [extant]
+"RTN","MXMLPATT",54,0)
+ NEW XPATH SET XPATH="/PEPSResponse/Body/drugCheck/drugDrugChecks/drugDrugCheck/professionalMonograph/references/reference"
+"RTN","MXMLPATT",55,0)
+ ;
+"RTN","MXMLPATT",56,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",57,0)
+ NEW RTN
+"RTN","MXMLPATT",58,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",59,0)
+ ;
+"RTN","MXMLPATT",60,0)
+ ;
+"RTN","MXMLPATT",61,0)
+ ; Count returned nodes
+"RTN","MXMLPATT",62,0)
+ NEW C SET C=0
+"RTN","MXMLPATT",63,0)
+ NEW N SET N=0 FOR SET N=$ORDER(RTN(N)) QUIT:'N SET C=C+1
+"RTN","MXMLPATT",64,0)
+ ;
+"RTN","MXMLPATT",65,0)
+ DO CHKEQ^%ut(C,5,"5 reference tags should exist")
+"RTN","MXMLPATT",66,0)
+ QUIT
+"RTN","MXMLPATT",67,0)
+ ;
+"RTN","MXMLPATT",68,0)
+TESTSS1 ; @TEST - Test //reference [extant]
+"RTN","MXMLPATT",69,0)
+ NEW XPATH SET XPATH="//reference"
+"RTN","MXMLPATT",70,0)
+ ;
+"RTN","MXMLPATT",71,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",72,0)
+ NEW RTN
+"RTN","MXMLPATT",73,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",74,0)
+ ;
+"RTN","MXMLPATT",75,0)
+ ; Count returned nodes
+"RTN","MXMLPATT",76,0)
+ NEW C SET C=0
+"RTN","MXMLPATT",77,0)
+ NEW N SET N=0 FOR SET N=$ORDER(RTN(N)) QUIT:'N SET C=C+1
+"RTN","MXMLPATT",78,0)
+ ;
+"RTN","MXMLPATT",79,0)
+ DO CHKEQ^%ut(C,5,"5 reference tags should exist")
+"RTN","MXMLPATT",80,0)
+ QUIT
+"RTN","MXMLPATT",81,0)
+ ;
+"RTN","MXMLPATT",82,0)
+TESTSS2 ; @TEST - Test //referenceblah [n/a]
+"RTN","MXMLPATT",83,0)
+ NEW XPATH SET XPATH="//referenceblah"
+"RTN","MXMLPATT",84,0)
+ ;
+"RTN","MXMLPATT",85,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",86,0)
+ NEW RTN
+"RTN","MXMLPATT",87,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",88,0)
+ ;
+"RTN","MXMLPATT",89,0)
+ ; Count returned nodes
+"RTN","MXMLPATT",90,0)
+ NEW C SET C=0
+"RTN","MXMLPATT",91,0)
+ NEW N SET N=0 FOR SET N=$ORDER(RTN(N)) QUIT:'N SET C=C+1
+"RTN","MXMLPATT",92,0)
+ ;
+"RTN","MXMLPATT",93,0)
+ DO CHKEQ^%ut(C,0,"0 referenceblah tags should exist")
+"RTN","MXMLPATT",94,0)
+ QUIT
+"RTN","MXMLPATT",95,0)
+ ;
+"RTN","MXMLPATT",96,0)
+TESTSS3 ; @TEST - Test //interactedDrugList/drug [extant]
+"RTN","MXMLPATT",97,0)
+ NEW XPATH SET XPATH="//interactedDrugList/drug"
+"RTN","MXMLPATT",98,0)
+ ;
+"RTN","MXMLPATT",99,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",100,0)
+ NEW RTN
+"RTN","MXMLPATT",101,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",102,0)
+ ;
+"RTN","MXMLPATT",103,0)
+ ; Count returned nodes
+"RTN","MXMLPATT",104,0)
+ NEW C SET C=0
+"RTN","MXMLPATT",105,0)
+ NEW N SET N=0 FOR SET N=$ORDER(RTN(N)) QUIT:'N SET C=C+1
+"RTN","MXMLPATT",106,0)
+ ;
+"RTN","MXMLPATT",107,0)
+ DO CHKEQ^%ut(C,2,"2 "_XPATH_" tags should exist")
+"RTN","MXMLPATT",108,0)
+ QUIT
+"RTN","MXMLPATT",109,0)
+ ;
+"RTN","MXMLPATT",110,0)
+TESTSS4 ; @TEST - Test //interactedDrugList/drum [n/a]
+"RTN","MXMLPATT",111,0)
+ NEW XPATH SET XPATH="//interactedDrugList/drum"
+"RTN","MXMLPATT",112,0)
+ ;
+"RTN","MXMLPATT",113,0)
+ ;
+"RTN","MXMLPATT",114,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",115,0)
+ NEW RTN
+"RTN","MXMLPATT",116,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",117,0)
+ ;
+"RTN","MXMLPATT",118,0)
+ ; Count returned nodes
+"RTN","MXMLPATT",119,0)
+ NEW C SET C=0
+"RTN","MXMLPATT",120,0)
+ NEW N SET N=0 FOR SET N=$ORDER(RTN(N)) QUIT:'N SET C=C+1
+"RTN","MXMLPATT",121,0)
+ ;
+"RTN","MXMLPATT",122,0)
+ DO CHKEQ^%ut(C,0,"0 "_XPATH_" tags should exist")
+"RTN","MXMLPATT",123,0)
+ QUIT
+"RTN","MXMLPATT",124,0)
+ ;
+"RTN","MXMLPATT",125,0)
+TESTREL1 ; @TEST - Test Relative paths (//Header, then MUser) [extant]
+"RTN","MXMLPATT",126,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",127,0)
+ NEW RTN
+"RTN","MXMLPATT",128,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,"//Header")
+"RTN","MXMLPATT",129,0)
+ NEW % SET %=$$XPATH^MXMLPATH(.RTN,DOCHAND,"MUser")
+"RTN","MXMLPATT",130,0)
+ DO CHKEQ^%ut($$VALUE^MXMLDOM(DOCHAND,%,"duz"),88660079,"Wrong tag retrieved")
+"RTN","MXMLPATT",131,0)
+ QUIT
+"RTN","MXMLPATT",132,0)
+ ;
+"RTN","MXMLPATT",133,0)
+TESTREL2 ; @TEST - Test Relative paths (//Header, then interactedDrugList/drug) [n/a]
+"RTN","MXMLPATT",134,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",135,0)
+ NEW RTN
+"RTN","MXMLPATT",136,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,"//Header")
+"RTN","MXMLPATT",137,0)
+ NEW % SET %=$$XPATH^MXMLPATH(.RTN,DOCHAND,"interactedDrugList/drug")
+"RTN","MXMLPATT",138,0)
+ DO CHKEQ^%ut($ORDER(RTN("")),"","No results should be found.")
+"RTN","MXMLPATT",139,0)
+ QUIT
+"RTN","MXMLPATT",140,0)
+ ;
+"RTN","MXMLPATT",141,0)
+TESTATT1 ; @TEST - Test Attribute //@orderNumber [extant]
+"RTN","MXMLPATT",142,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",143,0)
+ NEW RTN
+"RTN","MXMLPATT",144,0)
+ DO XPATH^MXMLPATH(.RTN,DOCHAND,"//@orderNumber")
+"RTN","MXMLPATT",145,0)
+ NEW X,Y,Z SET X=$ORDER(RTN("")),Y=$ORDER(RTN(X,"")),Z=RTN(X,Y)
+"RTN","MXMLPATT",146,0)
+ DO CHKEQ^%ut(Z,"Z;2;Prospect","Attribute not retrieved properly")
+"RTN","MXMLPATT",147,0)
+ QUIT
+"RTN","MXMLPATT",148,0)
+ ;
+"RTN","MXMLPATT",149,0)
+TESTATT2 ; @TEST - Test Attribute //drug/@vuid [extant]
+"RTN","MXMLPATT",150,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",151,0)
+ DO CHKEQ^%ut($$XPATH^MXMLPATH(,DOCHAND,"//drug/@vuid"),778899,"Attribute not retrieved properly")
+"RTN","MXMLPATT",152,0)
+ QUIT
+"RTN","MXMLPATT",153,0)
+ ;
+"RTN","MXMLPATT",154,0)
+TESTATT3 ; @TEST - Test Attribute //drug/dada [n/a]
+"RTN","MXMLPATT",155,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",156,0)
+ DO CHKEQ^%ut($$XPATH^MXMLPATH(,DOCHAND,"//drug/@dada"),"","non-existent Attribute")
+"RTN","MXMLPATT",157,0)
+ QUIT
+"RTN","MXMLPATT",158,0)
+ ;
+"RTN","MXMLPATT",159,0)
+TESTATT4 ; @TEST - Test relative attribute //Header, MServer, @stationNumber [extant]
+"RTN","MXMLPATT",160,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",161,0)
+ NEW %1 SET %1=$$XPATH^MXMLPATH(,DOCHAND,"//Header")
+"RTN","MXMLPATT",162,0)
+ NEW %2 SET %2=$$XPATH^MXMLPATH(,DOCHAND,"MServer")
+"RTN","MXMLPATT",163,0)
+ NEW %3 SET %3=$$XPATH^MXMLPATH(,DOCHAND,"@stationNumber")
+"RTN","MXMLPATT",164,0)
+ DO CHKEQ^%ut(%3,45,"Attribute not retrieved properly")
+"RTN","MXMLPATT",165,0)
+ QUIT
+"RTN","MXMLPATT",166,0)
+ ;
+"RTN","MXMLPATT",167,0)
+TESTFIL1 ; @TEST - Test ordinal filter expressions //references/reference[3] [extant]
+"RTN","MXMLPATT",168,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",169,0)
+ NEW XPATH SET XPATH="//references/reference[3]"
+"RTN","MXMLPATT",170,0)
+ NEW RTN DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",171,0)
+ NEW TXT SET TXT=^TMP("MXMLDOM",$JOB,DOCHAND,$ORDER(RTN("")),"T",1)
+"RTN","MXMLPATT",172,0)
+ DO CHKTF^%ut(TXT["nelfinavir","Incorrect node retrieved")
+"RTN","MXMLPATT",173,0)
+ QUIT
+"RTN","MXMLPATT",174,0)
+ ;
+"RTN","MXMLPATT",175,0)
+TESTFIL2 ; @TEST - Test ordinal filter expressions //references/reference[11] [n/a]
+"RTN","MXMLPATT",176,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",177,0)
+ NEW XPATH SET XPATH="//references/reference[11]"
+"RTN","MXMLPATT",178,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",179,0)
+ DO CHKEQ^%ut(%,"","reference[11] shouldn't exist")
+"RTN","MXMLPATT",180,0)
+ QUIT
+"RTN","MXMLPATT",181,0)
+ ;
+"RTN","MXMLPATT",182,0)
+TESTFIL3 ; @TEST - Test ordinal filter expression //reference[position(3)] [extant]
+"RTN","MXMLPATT",183,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",184,0)
+ NEW XPATH SET XPATH="//references/reference[position(3)]"
+"RTN","MXMLPATT",185,0)
+ NEW RTN DO XPATH^MXMLPATH(.RTN,DOCHAND,XPATH)
+"RTN","MXMLPATT",186,0)
+ NEW TXT SET TXT=^TMP("MXMLDOM",$JOB,DOCHAND,$ORDER(RTN("")),"T",1)
+"RTN","MXMLPATT",187,0)
+ DO CHKTF^%ut(TXT["nelfinavir","Incorrect node retrieved")
+"RTN","MXMLPATT",188,0)
+ QUIT
+"RTN","MXMLPATT",189,0)
+ ;
+"RTN","MXMLPATT",190,0)
+TESTFIL4 ; @TEST - Test last() filter expression //reference[last()] [extant]
+"RTN","MXMLPATT",191,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",192,0)
+ NEW XPATH SET XPATH="//reference[last()]"
+"RTN","MXMLPATT",193,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",194,0)
+ NEW TXT SET TXT=^TMP("MXMLDOM",$JOB,DOCHAND,%,"T",1)
+"RTN","MXMLPATT",195,0)
+ DO CHKTF^%ut(TXT["tipranavir","Incorrect node retrieved")
+"RTN","MXMLPATT",196,0)
+ QUIT
+"RTN","MXMLPATT",197,0)
+ ;
+"RTN","MXMLPATT",198,0)
+TESTFIL5 ; @TEST - Test @attribute as //drug[@vuid] [extant]
+"RTN","MXMLPATT",199,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",200,0)
+ NEW XPATH SET XPATH="//drug[@vuid]"
+"RTN","MXMLPATT",201,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",202,0)
+ DO CHKEQ^%ut($$VALUE^MXMLDOM(DOCHAND,%,"ien"),113,"Incorrect node retrieved")
+"RTN","MXMLPATT",203,0)
+ QUIT
+"RTN","MXMLPATT",204,0)
+ ;
+"RTN","MXMLPATT",205,0)
+TESTFIL6 ; @TEST - Test @attribute as //drug[@vuib] [n/a]
+"RTN","MXMLPATT",206,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",207,0)
+ NEW XPATH SET XPATH="//drug[@vuib]"
+"RTN","MXMLPATT",208,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",209,0)
+ DO CHKEQ^%ut(%,"","Incorrect node retrieved")
+"RTN","MXMLPATT",210,0)
+ QUIT
+"RTN","MXMLPATT",211,0)
+ ;
+"RTN","MXMLPATT",212,0)
+TESTFIL7 ; @TEST - Test node as //professionalMonograph[monographTitle] [extant]
+"RTN","MXMLPATT",213,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",214,0)
+ NEW XPATH SET XPATH="//professionalMonograph[monographTitle]"
+"RTN","MXMLPATT",215,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",216,0)
+ DO CHKEQ^%ut(^TMP("MXMLDOM",$JOB,DOCHAND,%),"professionalMonograph","Incorrect node retrieved")
+"RTN","MXMLPATT",217,0)
+ QUIT
+"RTN","MXMLPATT",218,0)
+ ;
+"RTN","MXMLPATT",219,0)
+TESTFIL8 ; @TEST - Test node as //professionalMonograph[monographTible] [n/a]
+"RTN","MXMLPATT",220,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",221,0)
+ NEW XPATH SET XPATH="//professionalMonograph[monographTible]"
+"RTN","MXMLPATT",222,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",223,0)
+ DO CHKEQ^%ut(%,"","monographTible does not exist")
+"RTN","MXMLPATT",224,0)
+ QUIT
+"RTN","MXMLPATT",225,0)
+ ;
+"RTN","MXMLPATT",226,0)
+TESTFIL9 ; @TEST - Test attribute="value" as //drug[@ien="113"] [extant]
+"RTN","MXMLPATT",227,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",228,0)
+ NEW XPATH SET XPATH="//drug[@ien=""113""]"
+"RTN","MXMLPATT",229,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",230,0)
+ DO CHKEQ^%ut($$VALUE^MXMLDOM(DOCHAND,%,"gcnSeqNo"),266,"Incorrect node retrieved")
+"RTN","MXMLPATT",231,0)
+ QUIT
+"RTN","MXMLPATT",232,0)
+ ;
+"RTN","MXMLPATT",233,0)
+TESTFI10 ; @TEST - Test attribute="value" as //drug[@ien="999"] [n/a]
+"RTN","MXMLPATT",234,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",235,0)
+ NEW XPATH SET XPATH="//drug[@ien=""999""]"
+"RTN","MXMLPATT",236,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",237,0)
+ DO CHKEQ^%ut(%,"","drug of IEN 999 doesn't exist")
+"RTN","MXMLPATT",238,0)
+ QUIT
+"RTN","MXMLPATT",239,0)
+ ;
+"RTN","MXMLPATT",240,0)
+TESTFI11 ; @TEST - Test node="value" as //drugDrugCheck[id="283"] [extant]
+"RTN","MXMLPATT",241,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",242,0)
+ NEW XPATH SET XPATH="//drugDrugCheck[id=""283""]"
+"RTN","MXMLPATT",243,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",244,0)
+ DO CHKEQ^%ut(^TMP("MXMLDOM",$JOB,DOCHAND,%),"drugDrugCheck","Incorrect node retrieved")
+"RTN","MXMLPATT",245,0)
+ QUIT
+"RTN","MXMLPATT",246,0)
+ ;
+"RTN","MXMLPATT",247,0)
+TESTFI12 ; @TEST - Test node="value" as //drugDrugCheck[id="999"] [n/a]
+"RTN","MXMLPATT",248,0)
+ ; ZEXCEPT: DOCHAND
+"RTN","MXMLPATT",249,0)
+ NEW XPATH SET XPATH="//drugDrugCheck[id=""999""]"
+"RTN","MXMLPATT",250,0)
+ NEW % SET %=$$XPATH^MXMLPATH(,DOCHAND,XPATH)
+"RTN","MXMLPATT",251,0)
+ DO CHKEQ^%ut(%,"","drugDrugCheck of id 999 doesn't exist")
+"RTN","MXMLPATT",252,0)
+ QUIT
+"RTN","MXMLPATT",253,0)
+ ;
+"RTN","MXMLPATT",254,0)
+TESTDATA ; from https://github.com/OSEHRA-Sandbox/MOCHA/tree/master/etc/xml/test/messages
+"RTN","MXMLPATT",255,0)
+ ;;
+"RTN","MXMLPATT",256,0)
+ ;;
+"RTN","MXMLPATT",259,0)
+ ;;
+"RTN","MXMLPATT",260,0)
+ ;;
+"RTN","MXMLPATT",261,0)
+ ;;
+"RTN","MXMLPATT",263,0)
+ ;;
+"RTN","MXMLPATT",264,0)
+ ;;
+"RTN","MXMLPATT",265,0)
+ ;;
+"RTN","MXMLPATT",266,0)
+ ;;
+"RTN","MXMLPATT",267,0)
+ ;;
+"RTN","MXMLPATT",268,0)
+ ;;
+"RTN","MXMLPATT",269,0)
+ ;;
+"RTN","MXMLPATT",270,0)
+ ;; 283
+"RTN","MXMLPATT",271,0)
+ ;;
+"RTN","MXMLPATT",272,0)
+ ;;
+"RTN","MXMLPATT",273,0)
+ ;;
+"RTN","MXMLPATT",274,0)
+ ;;
+"RTN","MXMLPATT",276,0)
+ ;;
+"RTN","MXMLPATT",277,0)
+ ;; Contraindicated Drug Combination
+"RTN","MXMLPATT",278,0)
+ ;; SELECTED PROTEASE INHIBITORS/AMIODARONE
+"RTN","MXMLPATT",279,0)
+ ;; INDINAVIR SULFATE ORAL CAPSULE 400 MG and AMIODARONE HCL ORAL TABLET 200 MG may interact based on the potential interaction between SELECTED PROTEASE INHIBITORS and AMIODARONE.
+"RTN","MXMLPATT",280,0)
+ ;;
+"RTN","MXMLPATT",281,0)
+ ;; FDB
+"RTN","MXMLPATT",282,0)
+ ;; This information is generalized and not intended as specific medical advice. Consult your healthcare professional before taking or discontinuing any drug or commencing any course of treatment.
+"RTN","MXMLPATT",283,0)
+ ;; MONOGRAPH TITLE: Selected Protease Inhibitors/Amiodarone
+"RTN","MXMLPATT",284,0)
+ ;; SEVERITY LEVEL: 1-Contraindicated Drug Combination: This drug combination is contraindicated and generally should not be dispensed or administered to the same patient.
+"RTN","MXMLPATT",285,0)
+ ;; MECHANISM OF ACTION: Indinavir,(1) nelfinavir,(2) ritonavir,(3) and tipranavir coadministered with ritonavir(4) may inhibit the metabolism of amiodarone at CYP P-450-3A4.
+"RTN","MXMLPATT",286,0)
+ ;; CLINICAL EFFECTS: The concurrent administration of amiodarone with indinavir,(1) nelfinavir,(2) ritonavir,(3) or tipranavir coadministered with ritonavir(4)
+"RTN","MXMLPATT",287,0)
+ ;;may result in increased levels, clinical effects, and toxicity of amiodarone.
+"RTN","MXMLPATT",288,0)
+ ;; PREDISPOSING FACTORS: None determined.
+"RTN","MXMLPATT",289,0)
+ ;; PATIENT MANAGEMENT: The concurrent administration of amiodarone with indinavir,(1) nelfinavir(2), ritonavir,(3) or tipranavir coadministered with ritonavir(4)
+"RTN","MXMLPATT",290,0)
+ ;;is contraindicated by the manufacturers of indinavir,(1) nelfinavir(2), ritonavir,(3) and tipranavir coadministered with ritonavir. (4)
+"RTN","MXMLPATT",291,0)
+ ;; DISCUSSION: Indinavir has been shown to inhibit CYP P-450-3A4. Therefore, the manufacturer of indinavir states that the concurrent administration of indinavir with amiodarone,
+"RTN","MXMLPATT",292,0)
+ ;;which is metabolized by CYP P-450-3A4, is contraindicated.(1)Nelfinavir has been shown to inhibit CYP P-450-3A4.
+"RTN","MXMLPATT",293,0)
+ ;;Therefore, the manufacturer of nelfinavir states that the concurrent administration of
+"RTN","MXMLPATT",294,0)
+ ;;nelfinavir with amiodarone, which is metabolized by CYP P-450-3A4, is contraindicated.(2)
+"RTN","MXMLPATT",295,0)
+ ;;Ritonavir has also been shown to inhibit CYP P-450-3A4. Therefore, the manufacturer of ritonavir state that the concurrent administration of ritonavir with amiodarone is contraindicated.(3)
+"RTN","MXMLPATT",296,0)
+ ;;
+"RTN","MXMLPATT",297,0)
+ ;;
+"RTN","MXMLPATT",298,0)
+ ;;
+"RTN","MXMLPATT",299,0)
+ ;;
+"RTN","MXMLPATT",300,0)
+ ;;
+"RTN","MXMLPATT",301,0)
+ ;;
+"RTN","MXMLPATT",302,0)
+ ;;
+"RTN","MXMLPATT",303,0)
+ ;;
+"RTN","MXMLPATT",304,0)
+ ;;
+"RTN","MXMLPATT",305,0)
+ ;;
+"RTN","MXMLPATT",306,0)
+ ;;
+"RTN","MXMLPATT",307,0)
+ ;;
+"RTN","MXMLPATT",308,0)
+ ;;
+"RTN","MXMLPATT",309,0)
+ ;;
+"RTN","MXMLPATT",310,0)
+ ;;<>
+"RTN","MXMLPRS0")
+0^1^B73523150
+"RTN","MXMLPRS0",1,0)
+MXMLPRS0 ;SAIC/DKM - XML Parser ;2015-05-25 11:39 AM
+"RTN","MXMLPRS0",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;June 15, 2015;Build 14
+"RTN","MXMLPRS0",3,0)
+ ;=================================================================
+"RTN","MXMLPRS0",4,0)
+ ; @Author Dr. Douglas Martin, SAIC.
+"RTN","MXMLPRS0",5,0)
+ ;
+"RTN","MXMLPRS0",6,0)
+ ; State 0: Prolog
+"RTN","MXMLPRS0",7,0)
+0 N ATTR
+"RTN","MXMLPRS0",8,0)
+ S ST=1
+"RTN","MXMLPRS0",9,0)
+ D WS()
+"RTN","MXMLPRS0",10,0)
+ I '$$NEXT("",3)
+"RTN","MXMLPRS0",13,0)
+ D:$G(ATTR("version"))'="1.0" ERROR(10,$G(ATTR("version")))
+"RTN","MXMLPRS0",14,0)
+ Q
+"RTN","MXMLPRS0",15,0)
+ ; State 1: Document type declaration
+"RTN","MXMLPRS0",16,0)
+1 N PUB,SYS
+"RTN","MXMLPRS0",17,0)
+ D WS()
+"RTN","MXMLPRS0",18,0)
+ Q:$$COMMENT
+"RTN","MXMLPRS0",19,0)
+ S ST=2
+"RTN","MXMLPRS0",20,0)
+ I '$$NEXT("",3) ST=6
+"RTN","MXMLPRS0",29,0)
+ Q
+"RTN","MXMLPRS0",30,0)
+ ; State 2: Non-markup text
+"RTN","MXMLPRS0",31,0)
+2 N TXT,CHR
+"RTN","MXMLPRS0",32,0)
+ D:'LVL WS()
+"RTN","MXMLPRS0",33,0)
+ S TXT=""
+"RTN","MXMLPRS0",34,0)
+ F S CHR=$E(XML,CPOS) Q:"<"[CHR!EOD D
+"RTN","MXMLPRS0",35,0)
+ .I $$NEXT("&") S TXT=TXT_$$ENTITY
+"RTN","MXMLPRS0",36,0)
+ .E S TXT=TXT_CHR,CPOS=CPOS+1
+"RTN","MXMLPRS0",37,0)
+ .D:(LLEN-CPOS)<50 READ ;P136
+"RTN","MXMLPRS0",38,0)
+ S:CHR="<" ST=3
+"RTN","MXMLPRS0",39,0)
+ I $L(TXT) D
+"RTN","MXMLPRS0",40,0)
+ .I 'LVL D ERROR(6) Q
+"RTN","MXMLPRS0",41,0)
+ .I '$$ISCHILD(LVL(LVL),"#PCDATA",1) D:$L($TR(TXT,WS)) ERROR(27) Q
+"RTN","MXMLPRS0",42,0)
+ .D CBK("CHARACTERS",TXT)
+"RTN","MXMLPRS0",43,0)
+ Q
+"RTN","MXMLPRS0",44,0)
+ ; State 3: Markup text
+"RTN","MXMLPRS0",45,0)
+3 N END,ENAME,ATTR
+"RTN","MXMLPRS0",46,0)
+ S ST=2
+"RTN","MXMLPRS0",47,0)
+ Q:$$COMMENT
+"RTN","MXMLPRS0",48,0)
+ Q:$$CDATA
+"RTN","MXMLPRS0",49,0)
+ Q:$$PI
+"RTN","MXMLPRS0",50,0)
+ Q:'$$NEXT("<",3)
+"RTN","MXMLPRS0",51,0)
+ S END=$$NEXT("/"),ENAME=$$NAME(2)
+"RTN","MXMLPRS0",52,0)
+ Q:'$L(ENAME)
+"RTN","MXMLPRS0",53,0)
+ I 'END D
+"RTN","MXMLPRS0",54,0)
+ .S:LVL LVL(LVL,"N")=$$ISCHILD(LVL(LVL),ENAME,LVL(LVL,"N"))
+"RTN","MXMLPRS0",55,0)
+ .D:'LVL(LVL,"N") ERROR(24,ENAME)
+"RTN","MXMLPRS0",56,0)
+ .D ATTRIBS(ENAME,.ATTR),CBK("STARTELEMENT",ENAME,.ATTR),WS()
+"RTN","MXMLPRS0",57,0)
+ .D READ ;*89 Check for more data
+"RTN","MXMLPRS0",58,0)
+ .S END=$$NEXT("/"),LVL=LVL+1
+"RTN","MXMLPRS0",59,0)
+ .M LVL(LVL)=ERR
+"RTN","MXMLPRS0",60,0)
+ .S LVL(LVL)=ENAME,LVL(LVL,"N")=1
+"RTN","MXMLPRS0",61,0)
+ .I LVL=1 D
+"RTN","MXMLPRS0",62,0)
+ ..I $D(LVL(0))#2,LVL(0)'=ENAME D ERROR(15,ENAME) Q
+"RTN","MXMLPRS0",63,0)
+ ..I '$D(LVL(-1)) S LVL(-1)=""
+"RTN","MXMLPRS0",64,0)
+ ..E D ERROR(45,ENAME)
+"RTN","MXMLPRS0",65,0)
+ I END D
+"RTN","MXMLPRS0",66,0)
+ .I LVL>0,$G(LVL(LVL))=ENAME D
+"RTN","MXMLPRS0",67,0)
+ ..D:'$$ISCHILD(ENAME,"*",LVL(LVL,"N")) ERROR(25)
+"RTN","MXMLPRS0",68,0)
+ ..D CBK("ENDELEMENT",ENAME)
+"RTN","MXMLPRS0",69,0)
+ ..K LVL(LVL)
+"RTN","MXMLPRS0",70,0)
+ ..S LVL=LVL-1
+"RTN","MXMLPRS0",71,0)
+ .E D ERROR(5,ENAME)
+"RTN","MXMLPRS0",72,0)
+ I $$NEXT(">",3)
+"RTN","MXMLPRS0",73,0)
+ Q
+"RTN","MXMLPRS0",74,0)
+ ; State 5: Internal or external DTD
+"RTN","MXMLPRS0",75,0)
+5 N X,Y
+"RTN","MXMLPRS0",76,0)
+ D DOPARAM
+"RTN","MXMLPRS0",77,0)
+ Q:$$COMMENT
+"RTN","MXMLPRS0",78,0)
+ I CS,$$NEXT("]]>") S CS=CS-1 Q
+"RTN","MXMLPRS0",79,0)
+ I $$NEXT("]") D Q
+"RTN","MXMLPRS0",80,0)
+ .S ST=6
+"RTN","MXMLPRS0",81,0)
+ .D WS()
+"RTN","MXMLPRS0",82,0)
+ .I $$NEXT(">",3)
+"RTN","MXMLPRS0",83,0)
+ Q:'$$NEXT(""),0
+"RTN","MXMLPRS0",94,0)
+ .S ST=5,DTD=""
+"RTN","MXMLPRS0",95,0)
+ D:CS ERROR(42)
+"RTN","MXMLPRS0",96,0)
+ Q
+"RTN","MXMLPRS0",97,0)
+ ; State 8: End of DTD declaration
+"RTN","MXMLPRS0",98,0)
+8 D WS()
+"RTN","MXMLPRS0",99,0)
+ I $$NEXT(">",3)
+"RTN","MXMLPRS0",100,0)
+ S ST=5
+"RTN","MXMLPRS0",101,0)
+ Q
+"RTN","MXMLPRS0",102,0)
+ ; State 20: DTD ENTITY declaration
+"RTN","MXMLPRS0",103,0)
+20 N SYS,PUB,ENAME,TYP,DUP,Z
+"RTN","MXMLPRS0",104,0)
+ I $$NEXT("%"),$$WS(1) S TYP=2
+"RTN","MXMLPRS0",105,0)
+ E S TYP=1
+"RTN","MXMLPRS0",106,0)
+ S ENAME=$$NAME(2)
+"RTN","MXMLPRS0",107,0)
+ Q:'$L(ENAME)
+"RTN","MXMLPRS0",108,0)
+ S ST=8,ENAME=$S(TYP=2:"%",1:"")_ENAME,DUP=$D(^TMP(ID,$J,"ENT",ENAME))
+"RTN","MXMLPRS0",109,0)
+ D NOFWD("UNP",ENAME),ERROR(18,ENAME):DUP,WS(1)
+"RTN","MXMLPRS0",110,0)
+ I $$SYSPUB(.SYS,.PUB) D
+"RTN","MXMLPRS0",111,0)
+ .D WS()
+"RTN","MXMLPRS0",112,0)
+ .I TYP=1,$$NEXT("NDATA") D
+"RTN","MXMLPRS0",113,0)
+ ..D WS(1)
+"RTN","MXMLPRS0",114,0)
+ ..S Z=$$NAME(2)
+"RTN","MXMLPRS0",115,0)
+ ..Q:'$L(Z)
+"RTN","MXMLPRS0",116,0)
+ ..D FWD("NOT",Z)
+"RTN","MXMLPRS0",117,0)
+ ..S:'DUP ^TMP(ID,$J,"ENT",ENAME)="",^TMP(ID,$J,"UNP",ENAME)=Z
+"RTN","MXMLPRS0",118,0)
+ .E D:'DUP
+"RTN","MXMLPRS0",119,0)
+ ..S Z=$$EXTRNL(SYS,PUB)
+"RTN","MXMLPRS0",120,0)
+ ..S:$L(Z) ^TMP(ID,$J,"ENT",ENAME)=Z
+"RTN","MXMLPRS0",121,0)
+ E D
+"RTN","MXMLPRS0",122,0)
+ .S Z=$$VALUE(1,TYP)
+"RTN","MXMLPRS0",123,0)
+ .D:'DUP SETENT(ENAME,Z)
+"RTN","MXMLPRS0",124,0)
+ Q
+"RTN","MXMLPRS0",125,0)
+ ; State 30: DTD ELEMENT declaration
+"RTN","MXMLPRS0",126,0)
+ ; Builds a parse tree for child elements
+"RTN","MXMLPRS0",127,0)
+30 N STK,ELEMENT,CHILD,START,END,MIXED,X,Z
+"RTN","MXMLPRS0",128,0)
+ D DOPARAM
+"RTN","MXMLPRS0",129,0)
+ S ELEMENT=$$NAME(2),ST=8
+"RTN","MXMLPRS0",130,0)
+ Q:'$L(ELEMENT)
+"RTN","MXMLPRS0",131,0)
+ Q:'$$WS(1)
+"RTN","MXMLPRS0",132,0)
+ I $D(^TMP(ID,$J,"ELE",ELEMENT)) D ERROR(20,ELEMENT) Q
+"RTN","MXMLPRS0",133,0)
+ D NOFWD("ELE",ELEMENT)
+"RTN","MXMLPRS0",134,0)
+ S Z=$S($$NEXT("EMPTY"):1,$$NEXT("ANY"):2,1:0),^TMP(ID,$J,"ELE",ELEMENT)=Z
+"RTN","MXMLPRS0",135,0)
+ Q:Z
+"RTN","MXMLPRS0",136,0)
+ S STK=0,MIXED=0,START=1,END=2
+"RTN","MXMLPRS0",137,0)
+ ; Check for opening parenthesis
+"RTN","MXMLPRS0",138,0)
+LPAREN D DOPARAM
+"RTN","MXMLPRS0",139,0)
+ I MIXED<2 D
+"RTN","MXMLPRS0",140,0)
+ .F D WS() Q:'$$NEXT("(",$S(STK:0,1:3)) S STK(STK)=START,STK=STK+1
+"RTN","MXMLPRS0",141,0)
+ ; Element name, parameter entity, or #PCDATA
+"RTN","MXMLPRS0",142,0)
+ D DOPARAM
+"RTN","MXMLPRS0",143,0)
+ I 'MIXED,$$NEXT("#PCDATA") S CHILD="#PCDATA",MIXED=2
+"RTN","MXMLPRS0",144,0)
+ E S CHILD=$$NAME(2),MIXED=$S('MIXED:1,MIXED=2:3,1:MIXED) Q:'$L(CHILD) D FWD("ELE",CHILD)
+"RTN","MXMLPRS0",145,0)
+ I $D(STK(-1,CHILD)) D ERROR(23,CHILD) Q
+"RTN","MXMLPRS0",146,0)
+ S STK(-1,CHILD)="",^TMP(ID,$J,"ELE",ELEMENT,START,CHILD)=END
+"RTN","MXMLPRS0",147,0)
+ S:CHILD="#PCDATA" ^(END)=""
+"RTN","MXMLPRS0",148,0)
+ G:MIXED>1 SEQOPR
+"RTN","MXMLPRS0",149,0)
+ ; Check for repetition modifier
+"RTN","MXMLPRS0",150,0)
+REPMOD S X=$S($$NEXT("*",$S(MIXED=3:3,1:0)):2,MIXED>1:0,$$NEXT("+"):1,$$NEXT("?"):3,1:0)
+"RTN","MXMLPRS0",151,0)
+ S:X=1 ^TMP(ID,$J,"ELE",ELEMENT,END,START)=""
+"RTN","MXMLPRS0",152,0)
+ S:X=2 ^TMP(ID,$J,"ELE",ELEMENT,END,START)="",^TMP(ID,$J,"ELE",ELEMENT,START,END)=""
+"RTN","MXMLPRS0",153,0)
+ S:X=3 ^TMP(ID,$J,"ELE",ELEMENT,START,END)=""
+"RTN","MXMLPRS0",154,0)
+ ; Check for sequence operator
+"RTN","MXMLPRS0",155,0)
+SEQOPR D WS()
+"RTN","MXMLPRS0",156,0)
+ S X=$S($$NEXT("|"):2,MIXED=2:0,$$NEXT(","):1,1:0)
+"RTN","MXMLPRS0",157,0)
+ I X D G LPAREN
+"RTN","MXMLPRS0",158,0)
+ .S:'$D(STK(STK,0)) STK(STK,0)=X
+"RTN","MXMLPRS0",159,0)
+ .D:STK(STK,0)'=X ERROR(22,$E(",|",X))
+"RTN","MXMLPRS0",160,0)
+ .S:X=1 START=END,END=END+1
+"RTN","MXMLPRS0",161,0)
+ D WS()
+"RTN","MXMLPRS0",162,0)
+ I '$$NEXT(")",$S(STK:3,1:0)) D Q
+"RTN","MXMLPRS0",163,0)
+ .S ^TMP(ID,$J,"ELE",ELEMENT,END,"*")=-1
+"RTN","MXMLPRS0",164,0)
+ I 'STK D ERROR(21) Q
+"RTN","MXMLPRS0",165,0)
+ K STK(STK)
+"RTN","MXMLPRS0",166,0)
+ S STK=STK-1,START=STK(STK)
+"RTN","MXMLPRS0",167,0)
+ G REPMOD
+"RTN","MXMLPRS0",168,0)
+ ; State 40: DTD ATTLIST declaration
+"RTN","MXMLPRS0",169,0)
+40 N ELEMENT,ATTRIB,TYPE,DFLT,DUP,X,Y
+"RTN","MXMLPRS0",170,0)
+ D DOPARAM
+"RTN","MXMLPRS0",171,0)
+ S ELEMENT=$$NAME(2)
+"RTN","MXMLPRS0",172,0)
+ Q:'$L(ELEMENT)
+"RTN","MXMLPRS0",173,0)
+ Q:'$$WS(1)
+"RTN","MXMLPRS0",174,0)
+ D FWD("ELE",ELEMENT)
+"RTN","MXMLPRS0",175,0)
+ ; Attribute name
+"RTN","MXMLPRS0",176,0)
+ATTNAME D DOPARAM
+"RTN","MXMLPRS0",177,0)
+ S ATTRIB=$$NAME(2)
+"RTN","MXMLPRS0",178,0)
+ Q:'$L(ATTRIB)
+"RTN","MXMLPRS0",179,0)
+ S DUP=$D(^TMP(ID,$J,"ATT",ELEMENT,ATTRIB))
+"RTN","MXMLPRS0",180,0)
+ D ERROR(4,ATTRIB):DUP,WS(1)
+"RTN","MXMLPRS0",181,0)
+ ; Attribute type
+"RTN","MXMLPRS0",182,0)
+ S TYPE=$$FNDTKN("TYP")
+"RTN","MXMLPRS0",183,0)
+ I 'TYPE D ERROR(33) Q
+"RTN","MXMLPRS0",184,0)
+ S:'DUP ^TMP(ID,$J,"ATT",ELEMENT,ATTRIB)=TYPE
+"RTN","MXMLPRS0",185,0)
+ D WS(TYPE'=1),NOTN:TYPE=8,ENUM:TYPE=1,WS()
+"RTN","MXMLPRS0",186,0)
+ ; Default modifier
+"RTN","MXMLPRS0",187,0)
+ S DFLT=$$FNDTKN("MOD")
+"RTN","MXMLPRS0",188,0)
+ S:'DUP $P(^TMP(ID,$J,"ATT",ELEMENT,ATTRIB),"^",2)=DFLT,Y=$G(^("#ID"))
+"RTN","MXMLPRS0",189,0)
+ I TYPE=5 D ; If ID type
+"RTN","MXMLPRS0",190,0)
+ .D:DFLT=3 ERROR(34)
+"RTN","MXMLPRS0",191,0)
+ .I '$L(Y) S:'DUP ^TMP(ID,$J,"ATT",ELEMENT,"#ID")=ATTRIB
+"RTN","MXMLPRS0",192,0)
+ .E D ERROR(35,Y)
+"RTN","MXMLPRS0",193,0)
+ ; Default value
+"RTN","MXMLPRS0",194,0)
+ I DFLT=3!'DFLT D
+"RTN","MXMLPRS0",195,0)
+ .D:DFLT WS(1)
+"RTN","MXMLPRS0",196,0)
+ .S X=$$VALUE(1)
+"RTN","MXMLPRS0",197,0)
+ .Q:DUP
+"RTN","MXMLPRS0",198,0)
+ .S $P(^TMP(ID,$J,"ATT",ELEMENT,ATTRIB),"^",3)=X
+"RTN","MXMLPRS0",199,0)
+ .D CHKVAL(ELEMENT,ATTRIB,X)
+"RTN","MXMLPRS0",200,0)
+ ; Next attribute or end of declaration
+"RTN","MXMLPRS0",201,0)
+ D WS()
+"RTN","MXMLPRS0",202,0)
+ G:'$$NEXT(">") ATTNAME
+"RTN","MXMLPRS0",203,0)
+ S ST=5
+"RTN","MXMLPRS0",204,0)
+ Q
+"RTN","MXMLPRS0",205,0)
+ ; Search for a token of the specified group
+"RTN","MXMLPRS0",206,0)
+ ; GRP=Group id
+"RTN","MXMLPRS0",207,0)
+ ; Returns token id within group or 0 if none found
+"RTN","MXMLPRS0",208,0)
+FNDTKN(GRP) ;
+"RTN","MXMLPRS0",209,0)
+ N TKN
+"RTN","MXMLPRS0",210,0)
+ S TKN=""
+"RTN","MXMLPRS0",211,0)
+ F S TKN=$O(^TMP(ID,$J,GRP,TKN),-1) Q:$$NEXT(TKN)
+"RTN","MXMLPRS0",212,0)
+ Q $S($L(TKN):^TMP(ID,$J,GRP,TKN),1:0)
+"RTN","MXMLPRS0",213,0)
+ ; Enumerated attribute type
+"RTN","MXMLPRS0",214,0)
+ENUM F D WS() S X=$$NAMETKN(3) Q:'$L(X) D Q:'$$NEXT("|")
+"RTN","MXMLPRS0",215,0)
+ .D:TYPE=8 FWD("NOT",X)
+"RTN","MXMLPRS0",216,0)
+ .S ^TMP(ID,$J,"ATT",ELEMENT,ATTRIB,X)=""
+"RTN","MXMLPRS0",217,0)
+ .D WS()
+"RTN","MXMLPRS0",218,0)
+ I $$NEXT(")",3)
+"RTN","MXMLPRS0",219,0)
+ Q
+"RTN","MXMLPRS0",220,0)
+ ; NOTATION attribute type
+"RTN","MXMLPRS0",221,0)
+NOTN D ENUM:$$NEXT("(",3)
+"RTN","MXMLPRS0",222,0)
+ Q
+"RTN","MXMLPRS0",223,0)
+ ; State 50: DTD NOTATION declaration
+"RTN","MXMLPRS0",224,0)
+50 N NAME,SYS,PUB,DUP
+"RTN","MXMLPRS0",225,0)
+ S NAME=$$NAME(3),ST=8
+"RTN","MXMLPRS0",226,0)
+ Q:'$L(NAME)
+"RTN","MXMLPRS0",227,0)
+ Q:'$$WS(1)
+"RTN","MXMLPRS0",228,0)
+ S DUP=$D(^TMP(ID,$J,"NOT",NAME))
+"RTN","MXMLPRS0",229,0)
+ D NOFWD("NOT",NAME),ERROR(48,NAME):DUP
+"RTN","MXMLPRS0",230,0)
+ I '$$SYSPUB(.SYS,.PUB,1) D ERROR(39) Q
+"RTN","MXMLPRS0",231,0)
+ Q:DUP
+"RTN","MXMLPRS0",232,0)
+ S ^TMP(ID,$J,"NOT",NAME,1)=SYS,^(2)=PUB
+"RTN","MXMLPRS0",233,0)
+ D CBK("NOTATION",NAME,SYS,PUB)
+"RTN","MXMLPRS0",234,0)
+ Q
+"RTN","MXMLPRS0",235,0)
+ ; State 60: Conditional sections
+"RTN","MXMLPRS0",236,0)
+60 N CSTYPE,CSCNT,DLM
+"RTN","MXMLPRS0",237,0)
+ D DOPARAM
+"RTN","MXMLPRS0",238,0)
+ S CSTYPE=$S($$NEXT("INCLUDE"):1,$$NEXT("IGNORE"):2,1:0),ST=5
+"RTN","MXMLPRS0",239,0)
+ I 'CSTYPE D ERROR(41) Q
+"RTN","MXMLPRS0",240,0)
+ I DOCSTK=1 D ERROR(44) Q
+"RTN","MXMLPRS0",241,0)
+ D WS()
+"RTN","MXMLPRS0",242,0)
+ Q:'$$NEXT("[",3)
+"RTN","MXMLPRS0",243,0)
+ I CSTYPE=1 S CS=CS+1 Q
+"RTN","MXMLPRS0",244,0)
+ S CSCNT=1,DLM=""
+"RTN","MXMLPRS0",245,0)
+ F D Q:'CSCNT!EOD
+"RTN","MXMLPRS0",246,0)
+ .I $L(DLM),$$NEXT(DLM) S DLM=""
+"RTN","MXMLPRS0",247,0)
+ .E I $L(DLM) S CPOS=CPOS+1
+"RTN","MXMLPRS0",248,0)
+ .E I $$NEXT(QT) S DLM=QT
+"RTN","MXMLPRS0",249,0)
+ .E I $$NEXT("'") S DLM="'"
+"RTN","MXMLPRS0",250,0)
+ .E I $$NEXT("") S CSCNT=CSCNT-1
+"RTN","MXMLPRS0",252,0)
+ .E S CPOS=CPOS+1
+"RTN","MXMLPRS0",253,0)
+ .D:CPOS>LLEN READ
+"RTN","MXMLPRS0",254,0)
+ D:CSCNT ERROR(42)
+"RTN","MXMLPRS0",255,0)
+ Q
+"RTN","MXMLPRS0",256,0)
+ ;Local Functions moved from MXMLPRSE
+"RTN","MXMLPRS0",257,0)
+ ; Execute event callback (if defined)
+"RTN","MXMLPRS0",258,0)
+ ; EVT=Event name
+"RTN","MXMLPRS0",259,0)
+ ; Pn=Parameters
+"RTN","MXMLPRS0",260,0)
+CBK(EVT,P1,P2,P3,P4) ;
+"RTN","MXMLPRS0",261,0)
+ Q:EOD<0
+"RTN","MXMLPRS0",262,0)
+ N EN,PNUM
+"RTN","MXMLPRS0",263,0)
+ S EN=$G(CBK(EVT))
+"RTN","MXMLPRS0",264,0)
+ Q:EN=""
+"RTN","MXMLPRS0",265,0)
+ S PNUM=^TMP(ID,$J,"CBK",EVT)
+"RTN","MXMLPRS0",266,0)
+ D @(EN_$P("(.P1,.P2,.P3,.P4",",",1,PNUM)_$S('PNUM:"",1:")"))
+"RTN","MXMLPRS0",267,0)
+ Q
+"RTN","MXMLPRS0",268,0)
+ ; Save current document location for error reporting
+"RTN","MXMLPRS0",269,0)
+ ; See EPOS^MXMLPRSE
+"RTN","MXMLPRS0",270,0)
+EPOS S ERR("XML")=XML,ERR("POS")=CPOS,ERR("LIN")=LPOS
+"RTN","MXMLPRS0",271,0)
+ Q
+"RTN","MXMLPRS0",272,0)
+ ; Check next characters
+"RTN","MXMLPRS0",273,0)
+ ; SEQ=character sequence
+"RTN","MXMLPRS0",274,0)
+ ; ERN=Error to signal if not found (optional)
+"RTN","MXMLPRS0",275,0)
+NEXT(SEQ,ERN) ;
+"RTN","MXMLPRS0",276,0)
+ I SEQ=$E(XML,CPOS,CPOS+$L(SEQ)-1) S CPOS=CPOS+$L(SEQ) Q 1
+"RTN","MXMLPRS0",277,0)
+ D:$G(ERN) EPOS^MXMLPRSE,ERROR(ERN,SEQ)
+"RTN","MXMLPRS0",278,0)
+ Q 0
+"RTN","MXMLPRS0",279,0)
+ ; Skip whitespace
+"RTN","MXMLPRS0",280,0)
+ ; ERN=Error to signal if not found (optional)
+"RTN","MXMLPRS0",281,0)
+ ; Optional return value =1 if whitespace found, 0 if not.
+"RTN","MXMLPRS0",282,0)
+WS(ERN) N CHR,FND
+"RTN","MXMLPRS0",283,0)
+ D EPOS^MXMLPRSE
+"RTN","MXMLPRS0",284,0)
+ S FND=0
+"RTN","MXMLPRS0",285,0)
+ F D:CPOS>LLEN READ S CHR=$E(XML,CPOS) Q:WS'[CHR!EOD D
+"RTN","MXMLPRS0",286,0)
+ .S ERN=0,CPOS=CPOS+1,FND=1
+"RTN","MXMLPRS0",287,0)
+ D:$G(ERN) ERROR(ERN)
+"RTN","MXMLPRS0",288,0)
+ Q:$Q FND
+"RTN","MXMLPRS0",289,0)
+ Q
+"RTN","MXMLPRS0",290,0)
+ ; Shortcuts to functions/procedures defined elsewhere
+"RTN","MXMLPRS0",291,0)
+ATTRIBS(X,Y) D ATTRIBS^MXMLPRSE(.X,.Y) Q
+"RTN","MXMLPRS0",292,0)
+CDATA() Q $$CDATA^MXMLPRSE
+"RTN","MXMLPRS0",293,0)
+CHKVAL(X,Y,Z) D CHKVAL^MXMLPRS1(.X,.Y,.Z) Q
+"RTN","MXMLPRS0",294,0)
+COMMENT() Q $$COMMENT^MXMLPRSE
+"RTN","MXMLPRS0",295,0)
+DOPARAM G DOPARAM^MXMLPRSE
+"RTN","MXMLPRS0",296,0)
+ENTITY(X) Q $$ENTITY^MXMLPRSE(.X)
+"RTN","MXMLPRS0",297,0)
+ERROR(X,Y) D ERROR^MXMLPRSE(.X,.Y) Q
+"RTN","MXMLPRS0",298,0)
+EXTRNL(X,Y,Z) Q $$EXTRNL^MXMLPRSE(.X,.Y,.Z)
+"RTN","MXMLPRS0",299,0)
+FWD(X,Y) D FWD^MXMLPRS1(.X,.Y) Q
+"RTN","MXMLPRS0",300,0)
+ISCHILD(X,Y,Z) Q $$ISCHILD^MXMLPRS1(.X,.Y,.Z)
+"RTN","MXMLPRS0",301,0)
+NAME(X) Q $$NAME^MXMLPRSE(.X)
+"RTN","MXMLPRS0",302,0)
+NAMETKN(X) Q $$NAMETKN^MXMLPRSE(.X)
+"RTN","MXMLPRS0",303,0)
+NOFWD(X,Y) D NOFWD^MXMLPRS1(.X,.Y) Q
+"RTN","MXMLPRS0",304,0)
+OPNDOC(X,Y,Z) D OPNDOC^MXMLPRSE(.X,.Y,.Z) Q
+"RTN","MXMLPRS0",305,0)
+PI() Q $$PI^MXMLPRSE
+"RTN","MXMLPRS0",306,0)
+SETENT(X,Y) D SETENT^MXMLPRSE(.X,.Y) Q
+"RTN","MXMLPRS0",307,0)
+SYSPUB(X,Y,Z) Q:$Q $$SYSPUB^MXMLPRSE(.X,.Y,.Z)
+"RTN","MXMLPRS0",308,0)
+ D SYSPUB^MXMLPRSE(.X,.Y) Q
+"RTN","MXMLPRS0",309,0)
+READ G READ^MXMLPRSE
+"RTN","MXMLPRS0",310,0)
+VALUE(X,Y) Q $$VALUE^MXMLPRSE(.X,.Y)
+"RTN","MXMLPRS1")
+0^2^B16479083
+"RTN","MXMLPRS1",1,0)
+MXMLPRS1 ;SAIC/DKM - XML Parser ;2015-05-25 11:40 AM
+"RTN","MXMLPRS1",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;June 15, 2015;Build 14
+"RTN","MXMLPRS1",3,0)
+ ; @Author Dr. Douglas Martin, SAIC.
+"RTN","MXMLPRS1",4,0)
+ ;=================================================================
+"RTN","MXMLPRS1",5,0)
+ ; Initialize tables
+"RTN","MXMLPRS1",6,0)
+INIT N X,Y,Z
+"RTN","MXMLPRS1",7,0)
+ F X=0:1 S Y=$P($T(ENTITIES+X),";;",2,99) Q:'$L(Y) D
+"RTN","MXMLPRS1",8,0)
+ .D SETENT^MXMLPRSE($P(Y,";"),$P(Y,";",2,99))
+"RTN","MXMLPRS1",9,0)
+ F X=0:1 S Y=$P($T(DTDTAG+X),";;",2,99) Q:'$L(Y) D
+"RTN","MXMLPRS1",10,0)
+ .S DTD($P(Y,";"))=$P(Y,";",2)
+"RTN","MXMLPRS1",11,0)
+ F X=0:1 S Y=$P($T(TYPE+X),";;",2,99) Q:'$L(Y) D
+"RTN","MXMLPRS1",12,0)
+ .S ^TMP(ID,$J,"TYP",$P(Y,";",2))=+Y
+"RTN","MXMLPRS1",13,0)
+ F X=0:1 S Y=$P($T(MOD+X),";;",2,99) Q:'$L(Y) D
+"RTN","MXMLPRS1",14,0)
+ .S ^TMP(ID,$J,"MOD",$P(Y,";",2))=+Y
+"RTN","MXMLPRS1",15,0)
+ F X=0:1 S Y=$P($T(REF+X),";;",2,99) Q:'$L(Y) D
+"RTN","MXMLPRS1",16,0)
+ .S ^TMP(ID,$J,"REF",$P(Y,";",2))=+Y
+"RTN","MXMLPRS1",17,0)
+ F X=0:1 S Y=$P($T(CBKARGS+X),";;",2,99) Q:'$L(Y) D
+"RTN","MXMLPRS1",18,0)
+ .S ^TMP(ID,$J,"CBK",$P(Y,";",2))=+Y
+"RTN","MXMLPRS1",19,0)
+ F X=0:1 S Y=$P($T(PROLOG+X),";;",2,99) Q:'$L(Y) D
+"RTN","MXMLPRS1",20,0)
+ .S Z=$P(Y,";"),^TMP(ID,$J,"ATT","?xml",Z)="1^"_$S('X:1,1:2)
+"RTN","MXMLPRS1",21,0)
+ .F S Y=$P(Y,";",2,99) Q:'$L(Y) S ^TMP(ID,$J,"ATT","?xml",Z,$P(Y,";"))=""
+"RTN","MXMLPRS1",22,0)
+ Q
+"RTN","MXMLPRS1",23,0)
+ ; Search parse tree for child element (CHILD) under parent element
+"RTN","MXMLPRS1",24,0)
+ ; (ELEMENT) starting at specified node (NODE).
+"RTN","MXMLPRS1",25,0)
+ ; Returns next node # in parse tree or 0
+"RTN","MXMLPRS1",26,0)
+ ; If validation is disabled, the function always returns 1.
+"RTN","MXMLPRS1",27,0)
+ ; If parent element is marked as EMPTY, 0 is returned.
+"RTN","MXMLPRS1",28,0)
+ ; If parent element is marked as ANY, 1 is returned.
+"RTN","MXMLPRS1",29,0)
+ISCHILD(ELEMENT,CHILD,NODE) ;
+"RTN","MXMLPRS1",30,0)
+ N TRN
+"RTN","MXMLPRS1",31,0)
+ S TRN=+$G(^TMP(ID,$J,"ELE",ELEMENT),2)
+"RTN","MXMLPRS1",32,0)
+ Q $S(OPTION'["V"!'NODE:1,TRN=1:CHILD="*",TRN=2:1,1:$$IC(NODE))
+"RTN","MXMLPRS1",33,0)
+IC(NODE) N X,Y
+"RTN","MXMLPRS1",34,0)
+ S X=+$G(^TMP(ID,$J,"ELE",ELEMENT,NODE,CHILD)),Y=0
+"RTN","MXMLPRS1",35,0)
+ I 'X D
+"RTN","MXMLPRS1",36,0)
+ .F S Y=$O(^TMP(ID,$J,"ELE",ELEMENT,NODE,Y)) Q:'Y D Q:X
+"RTN","MXMLPRS1",37,0)
+ ..S:'$D(TRN(NODE,Y)) TRN(NODE,Y)="",X=$$IC(Y)
+"RTN","MXMLPRS1",38,0)
+ Q X
+"RTN","MXMLPRS1",39,0)
+ ; Check attribute value for validity
+"RTN","MXMLPRS1",40,0)
+CHKVAL(ENAME,ANAME,VALUE) ;
+"RTN","MXMLPRS1",41,0)
+ N TYPE,X,Y,Z
+"RTN","MXMLPRS1",42,0)
+ Q:'$L(VALUE)
+"RTN","MXMLPRS1",43,0)
+ I $D(^TMP(ID,$J,"ATT",ENAME,ANAME))>1 D:'$D(^(ANAME,VALUE)) ERROR(38,VALUE) Q
+"RTN","MXMLPRS1",44,0)
+ S TYPE=+$G(^TMP(ID,$J,"ATT",ENAME,ANAME))
+"RTN","MXMLPRS1",45,0)
+ Q:'TYPE
+"RTN","MXMLPRS1",46,0)
+ I TYPE=5 D Q ; ID type
+"RTN","MXMLPRS1",47,0)
+ .I '$$ISNAME(VALUE) D ERROR(38,VALUE) Q
+"RTN","MXMLPRS1",48,0)
+ .I '$D(^TMP(ID,$J,"ID",VALUE)) D
+"RTN","MXMLPRS1",49,0)
+ ..S ^(VALUE)=""
+"RTN","MXMLPRS1",50,0)
+ ..D NOFWD("ID",VALUE)
+"RTN","MXMLPRS1",51,0)
+ .E D ERROR(28,VALUE)
+"RTN","MXMLPRS1",52,0)
+ I TYPE=9!(TYPE=10) D Q ; ENTITY/ENTITIES type
+"RTN","MXMLPRS1",53,0)
+ .S X=$S(TYPE=9:" ",1:" ")
+"RTN","MXMLPRS1",54,0)
+ .F Z=1:1:$L(VALUE,X) D FWD("UNP",$P(VALUE,X,Z))
+"RTN","MXMLPRS1",55,0)
+ I TYPE=3!(TYPE=4) D Q ; NMTOKEN/NMTOKENS type
+"RTN","MXMLPRS1",56,0)
+ .S X=$S(TYPE=3:" ",1:" ")
+"RTN","MXMLPRS1",57,0)
+ .F Z=1:1:$L(VALUE,X) D
+"RTN","MXMLPRS1",58,0)
+ ..S Y=$P(VALUE,X,Z)
+"RTN","MXMLPRS1",59,0)
+ ..D:'$$ISNMTKN(Y) ERROR(38,Y)
+"RTN","MXMLPRS1",60,0)
+ I TYPE=6!(TYPE=7) D Q ; IDREF/IDREFS type
+"RTN","MXMLPRS1",61,0)
+ .S X=$S(TYPE=6:" ",1:" ")
+"RTN","MXMLPRS1",62,0)
+ .F Z=1:1:$L(VALUE,X) D
+"RTN","MXMLPRS1",63,0)
+ ..S Y=$P(VALUE,X,Z)
+"RTN","MXMLPRS1",64,0)
+ ..I '$$ISNAME(Y) D ERROR(38,Y) Q
+"RTN","MXMLPRS1",65,0)
+ ..D FWD("ID",Y)
+"RTN","MXMLPRS1",66,0)
+ Q
+"RTN","MXMLPRS1",67,0)
+ ; Return true if valid name
+"RTN","MXMLPRS1",68,0)
+ISNAME(VALUE) ;
+"RTN","MXMLPRS1",69,0)
+ Q VALUE?1(1A,1"_",1":").(1AN,1".",1"-",1"_",1":")
+"RTN","MXMLPRS1",70,0)
+ ; Return true if valid name token
+"RTN","MXMLPRS1",71,0)
+ISNMTKN(VALUE) ;
+"RTN","MXMLPRS1",72,0)
+ Q VALUE?1.(1AN,1".",1"-",1"_",1":")
+"RTN","MXMLPRS1",73,0)
+ ; Log a forward reference
+"RTN","MXMLPRS1",74,0)
+FWD(TYPE,VALUE) ;
+"RTN","MXMLPRS1",75,0)
+ Q:'$L(VALUE)
+"RTN","MXMLPRS1",76,0)
+ Q:$D(^TMP(ID,$J,TYPE,VALUE))
+"RTN","MXMLPRS1",77,0)
+ N Z
+"RTN","MXMLPRS1",78,0)
+ S Z=$O(^TMP(ID,$J,"REF",TYPE,VALUE,""),-1)+1
+"RTN","MXMLPRS1",79,0)
+ M ^(Z)=ERR
+"RTN","MXMLPRS1",80,0)
+ Q
+"RTN","MXMLPRS1",81,0)
+ ; Resolve forward reference
+"RTN","MXMLPRS1",82,0)
+NOFWD(TYPE,VALUE) ;
+"RTN","MXMLPRS1",83,0)
+ K ^TMP(ID,$J,"REF",TYPE,VALUE)
+"RTN","MXMLPRS1",84,0)
+ Q
+"RTN","MXMLPRS1",85,0)
+ ; Signal unresolved references
+"RTN","MXMLPRS1",86,0)
+UNRESLV N X,Y,Z,E
+"RTN","MXMLPRS1",87,0)
+ F X=1:1:LVL D
+"RTN","MXMLPRS1",88,0)
+ .K ERR
+"RTN","MXMLPRS1",89,0)
+ .M ERR=LVL(X)
+"RTN","MXMLPRS1",90,0)
+ .D ERROR(8,LVL(X))
+"RTN","MXMLPRS1",91,0)
+ S X=""
+"RTN","MXMLPRS1",92,0)
+ F S X=$O(^TMP(ID,$J,"REF",X)),Y="" Q:'$L(X) D ; Look for IDREF w/o corresponding ID value
+"RTN","MXMLPRS1",93,0)
+ .S E=^(X)
+"RTN","MXMLPRS1",94,0)
+ .F S Y=$O(^TMP(ID,$J,"REF",X,Y)),Z=0 Q:'$L(Y) D
+"RTN","MXMLPRS1",95,0)
+ ..F S Z=$O(^TMP(ID,$J,"REF",X,Y,Z)) Q:'Z D
+"RTN","MXMLPRS1",96,0)
+ ...K ERR
+"RTN","MXMLPRS1",97,0)
+ ...M ERR=^(Z)
+"RTN","MXMLPRS1",98,0)
+ ...D ERROR(E,Y)
+"RTN","MXMLPRS1",99,0)
+ Q
+"RTN","MXMLPRS1",100,0)
+ ; Log error
+"RTN","MXMLPRS1",101,0)
+ERROR(X,Y) D ERROR^MXMLPRSE(.X,.Y) Q
+"RTN","MXMLPRS1",102,0)
+ ; Predefined general entities
+"RTN","MXMLPRS1",103,0)
+ ; Format=entity name;entity value
+"RTN","MXMLPRS1",104,0)
+ENTITIES ;;amp;&
+"RTN","MXMLPRS1",105,0)
+ ;;lt;<
+"RTN","MXMLPRS1",106,0)
+ ;;gt;>
+"RTN","MXMLPRS1",107,0)
+ ;;quot;"
+"RTN","MXMLPRS1",108,0)
+ ;;apos;'
+"RTN","MXMLPRS1",109,0)
+ ;;
+"RTN","MXMLPRS1",110,0)
+ ; Callback events
+"RTN","MXMLPRS1",111,0)
+ ; Format=#args;event type
+"RTN","MXMLPRS1",112,0)
+CBKARGS ;;0;STARTDOCUMENT
+"RTN","MXMLPRS1",113,0)
+ ;;0;ENDDOCUMENT
+"RTN","MXMLPRS1",114,0)
+ ;;3;DOCTYPE
+"RTN","MXMLPRS1",115,0)
+ ;;1;CHARACTERS
+"RTN","MXMLPRS1",116,0)
+ ;;2;STARTELEMENT
+"RTN","MXMLPRS1",117,0)
+ ;;1;ENDELEMENT
+"RTN","MXMLPRS1",118,0)
+ ;;3;NOTATION
+"RTN","MXMLPRS1",119,0)
+ ;;2;PI
+"RTN","MXMLPRS1",120,0)
+ ;;1;COMMENT
+"RTN","MXMLPRS1",121,0)
+ ;;3;EXTERNAL
+"RTN","MXMLPRS1",122,0)
+ ;;1;ERROR
+"RTN","MXMLPRS1",123,0)
+ ;;
+"RTN","MXMLPRS1",124,0)
+ ; Prolog attributes
+"RTN","MXMLPRS1",125,0)
+ ; Format=attribute name;val1;val2;...;valn
+"RTN","MXMLPRS1",126,0)
+PROLOG ;;version;1.0
+"RTN","MXMLPRS1",127,0)
+ ;;encoding;UTF-8;utf-8
+"RTN","MXMLPRS1",128,0)
+ ;;standalone;no;yes
+"RTN","MXMLPRS1",129,0)
+ ;;
+"RTN","MXMLPRS1",130,0)
+ ; Recognized DTD tags
+"RTN","MXMLPRS1",131,0)
+ ; Format=tag name;state
+"RTN","MXMLPRS1",132,0)
+DTDTAG ;;ENTITY;20
+"RTN","MXMLPRS1",133,0)
+ ;;ELEMENT;30
+"RTN","MXMLPRS1",134,0)
+ ;;ATTLIST;40
+"RTN","MXMLPRS1",135,0)
+ ;;NOTATION;50
+"RTN","MXMLPRS1",136,0)
+ ;;[;60
+"RTN","MXMLPRS1",137,0)
+ ;;
+"RTN","MXMLPRS1",138,0)
+ ; Attribute types
+"RTN","MXMLPRS1",139,0)
+ ; Format=identifier;type
+"RTN","MXMLPRS1",140,0)
+TYPE ;;1;(
+"RTN","MXMLPRS1",141,0)
+ ;;2;CDATA
+"RTN","MXMLPRS1",142,0)
+ ;;3;NMTOKEN
+"RTN","MXMLPRS1",143,0)
+ ;;4;NMTOKENS
+"RTN","MXMLPRS1",144,0)
+ ;;5;ID
+"RTN","MXMLPRS1",145,0)
+ ;;6;IDREF
+"RTN","MXMLPRS1",146,0)
+ ;;7;IDREFS
+"RTN","MXMLPRS1",147,0)
+ ;;8;NOTATION
+"RTN","MXMLPRS1",148,0)
+ ;;9;ENTITY
+"RTN","MXMLPRS1",149,0)
+ ;;10;ENTITIES
+"RTN","MXMLPRS1",150,0)
+ ;;
+"RTN","MXMLPRS1",151,0)
+ ; Default modifiers
+"RTN","MXMLPRS1",152,0)
+ ; Format=identifier;modifier
+"RTN","MXMLPRS1",153,0)
+MOD ;;1;#REQUIRED
+"RTN","MXMLPRS1",154,0)
+ ;;2;#IMPLIED
+"RTN","MXMLPRS1",155,0)
+ ;;3;#FIXED
+"RTN","MXMLPRS1",156,0)
+ ;;
+"RTN","MXMLPRS1",157,0)
+ ; Forward references
+"RTN","MXMLPRS1",158,0)
+ ; Format=type;error #;type
+"RTN","MXMLPRS1",159,0)
+REF ;;49;UNP
+"RTN","MXMLPRS1",160,0)
+ ;;46;NOT
+"RTN","MXMLPRS1",161,0)
+ ;;26;ELE
+"RTN","MXMLPRS1",162,0)
+ ;;47;ID
+"RTN","MXMLPRS1",163,0)
+ ;;
+"RTN","MXMLPRSE")
+0^3^B70461009
+"RTN","MXMLPRSE",1,0)
+MXMLPRSE ;SAIC/DKM - XML Parser ;2015-05-25 11:41 AM
+"RTN","MXMLPRSE",2,0)
+ ;;2.4;XML PROCESSING UTILITIES;;June 15, 2015;Build 14
+"RTN","MXMLPRSE",3,0)
+ ; @Author Dr. Douglas Martin, SAIC.
+"RTN","MXMLPRSE",4,0)
+ ; Sam Habiel made various fixes in 2014. Copyright disclaimed.
+"RTN","MXMLPRSE",5,0)
+ ;=================================================================
+"RTN","MXMLPRSE",6,0)
+ ; Main entry point.
+"RTN","MXMLPRSE",7,0)
+ ; DOC = Closed reference to global array containing document
+"RTN","MXMLPRSE",8,0)
+ ; CBK = Local array containing entry points for callback interface
+"RTN","MXMLPRSE",9,0)
+ ; OPTION = Option flags; expected values are:
+"RTN","MXMLPRSE",10,0)
+ ; D = Debug mode
+"RTN","MXMLPRSE",11,0)
+ ; W = Do not report warnings
+"RTN","MXMLPRSE",12,0)
+ ; V = Validate (checks only well-formedness by default)
+"RTN","MXMLPRSE",13,0)
+ ; 0,1 = Terminate on encountering error at specified level
+"RTN","MXMLPRSE",14,0)
+EN(DOC,CBK,OPTION) ;
+"RTN","MXMLPRSE",15,0)
+ N WS,ID,QT,EDC,DTD,LVL,CS,DOCSTK,LLEN,LPOS,CPOS,LCUR,ERR,XML,PFX,SFX,EOD,EOG,ST,PATH,OFX
+"RTN","MXMLPRSE",16,0)
+ S ID=$T(+0),WS=$C(9,10,13,32),QT="""",(DOCSTK,EOG,EOD,LVL,CS,ST,LPOS,LLEN,LCUR)=0,(CPOS,LVL(0,"N"))=1,OPTION=$G(OPTION),(XML,PFX,SFX)="",PATH=$$PATH(DOC)
+"RTN","MXMLPRSE",17,0)
+ K ^TMP(ID,$J)
+"RTN","MXMLPRSE",18,0)
+ I $L($T(TOUCH^XUSCLEAN)) D TOUCH^XUSCLEAN ;Set the keepalive node
+"RTN","MXMLPRSE",19,0)
+ D INIT^MXMLPRS1,EPOS,CBK("STARTDOCUMENT"),OPNDOC(DOC)
+"RTN","MXMLPRSE",20,0)
+ F Q:EOD D READ,EPOS,@ST^MXMLPRS0:'EOD
+"RTN","MXMLPRSE",21,0)
+ D UNRESLV^MXMLPRS1,ERROR(17):ST'=2,CBK("ENDDOCUMENT")
+"RTN","MXMLPRSE",22,0)
+ K ^TMP(ID,$J)
+"RTN","MXMLPRSE",23,0)
+ Q
+"RTN","MXMLPRSE",24,0)
+ ; Open a document
+"RTN","MXMLPRSE",25,0)
+ ; Saves state of current document on stack.
+"RTN","MXMLPRSE",26,0)
+ ; DOCREF=Closed reference to array containing document
+"RTN","MXMLPRSE",27,0)
+ ; PREFIX=Optional prefix to prepend to document
+"RTN","MXMLPRSE",28,0)
+ ; SUFFIX=Optional suffix to append to document
+"RTN","MXMLPRSE",29,0)
+OPNDOC(DOCREF,PREFIX,SUFFIX) ;
+"RTN","MXMLPRSE",30,0)
+ S:$E(DOCREF)'="^" DOCREF=$$EXTRNL(DOCREF)
+"RTN","MXMLPRSE",31,0)
+ Q:'$L(DOCREF)
+"RTN","MXMLPRSE",32,0)
+ D SAVRES(1)
+"RTN","MXMLPRSE",33,0)
+ S DOC=$NA(@DOCREF)
+"RTN","MXMLPRSE",34,0)
+ I '$D(^TMP(ID,$J,"DOC",DOC)) S ^(DOC)=""
+"RTN","MXMLPRSE",35,0)
+ E D ERROR(43)
+"RTN","MXMLPRSE",36,0)
+ S (LPOS,LLEN,LCUR)=0,CPOS=1,(OFX,XML)="",PFX=$G(PREFIX),SFX=$G(SUFFIX)
+"RTN","MXMLPRSE",37,0)
+ S LCUR=DOC,DOC=$E(DOC,1,$L(DOC)-1) ;*rwf
+"RTN","MXMLPRSE",38,0)
+ Q
+"RTN","MXMLPRSE",39,0)
+ ; Close current document
+"RTN","MXMLPRSE",40,0)
+ ; Restores state of previous document from stack.
+"RTN","MXMLPRSE",41,0)
+CLSDOC K ^TMP(ID,$J,"DOC",DOC_")") ;*rwf
+"RTN","MXMLPRSE",42,0)
+ D SAVRES(0)
+"RTN","MXMLPRSE",43,0)
+ Q
+"RTN","MXMLPRSE",44,0)
+ ; Extract path from filespec
+"RTN","MXMLPRSE",45,0)
+PATH(DOC) ;
+"RTN","MXMLPRSE",46,0)
+ N X
+"RTN","MXMLPRSE",47,0)
+ Q:U[$E(DOC) ""
+"RTN","MXMLPRSE",48,0)
+ F X="\","/","]",":","" Q:DOC[X
+"RTN","MXMLPRSE",49,0)
+ Q $P(DOC,X,1,$L(DOC,X)-1)_X
+"RTN","MXMLPRSE",50,0)
+ ; Save or restore document state
+"RTN","MXMLPRSE",51,0)
+SAVRES(SAVE) ;
+"RTN","MXMLPRSE",52,0)
+ N X
+"RTN","MXMLPRSE",53,0)
+ S:'SAVE DOCSTK=DOCSTK-1,EOD=DOCSTK=0
+"RTN","MXMLPRSE",54,0)
+ I DOCSTK F X="LLEN","LPOS","CPOS","LCUR","XML","PFX","SFX","OFX","DOC" D
+"RTN","MXMLPRSE",55,0)
+ .I SAVE S DOCSTK(DOCSTK,X)=@X
+"RTN","MXMLPRSE",56,0)
+ .E S @X=DOCSTK(DOCSTK,X)
+"RTN","MXMLPRSE",57,0)
+ I SAVE S DOCSTK=DOCSTK+1
+"RTN","MXMLPRSE",58,0)
+ E K DOCSTK(DOCSTK)
+"RTN","MXMLPRSE",59,0)
+ Q
+"RTN","MXMLPRSE",60,0)
+ ; Retrieve text from document
+"RTN","MXMLPRSE",61,0)
+READ Q:((LLEN-CPOS)>50)!EOD ;Quit if still have 50 char or EOD
+"RTN","MXMLPRSE",62,0)
+ I (CPOS'50
+"RTN","MXMLPRSE",65,0)
+ I EOG!EOD Q ;Quit at end of document
+"RTN","MXMLPRSE",66,0)
+ S LPOS=LPOS+1,LCUR=$Q(@LCUR) ;Get next node
+"RTN","MXMLPRSE",67,0)
+ I LCUR'[DOC S EOG=1 Q ;At end of global
+"RTN","MXMLPRSE",68,0)
+ S TMP=@LCUR ;Get next data chunk
+"RTN","MXMLPRSE",69,0)
+ W:OPTION["D" !,$J(LPOS,3)_":",TMP,!
+"RTN","MXMLPRSE",70,0)
+ S OFX=OFX_TMP
+"RTN","MXMLPRSE",71,0)
+ D SHIFT
+"RTN","MXMLPRSE",72,0)
+ I LLEN<50 G READ
+"RTN","MXMLPRSE",73,0)
+ Q
+"RTN","MXMLPRSE",74,0)
+ ;Shift OFX to XML
+"RTN","MXMLPRSE",75,0)
+SHIFT ;
+"RTN","MXMLPRSE",76,0)
+ S XML=$E(XML,CPOS,9999),CPOS=1 ;Drop old
+"RTN","MXMLPRSE",77,0)
+ I $L(PFX) S OFX=XML_OFX,XML=PFX,PFX=""
+"RTN","MXMLPRSE",78,0)
+ I $L(OFX) S X=511-$L(XML),XML=XML_$E(OFX,1,X),OFX=$E(OFX,X+1,99999)
+"RTN","MXMLPRSE",79,0)
+ S LLEN=$L(XML)
+"RTN","MXMLPRSE",80,0)
+ Q
+"RTN","MXMLPRSE",81,0)
+ ; Parse name
+"RTN","MXMLPRSE",82,0)
+ ; ERN=Error to signal if invalid (optional)
+"RTN","MXMLPRSE",83,0)
+NAME(ERN) ;
+"RTN","MXMLPRSE",84,0)
+ N X
+"RTN","MXMLPRSE",85,0)
+ D EPOS
+"RTN","MXMLPRSE",86,0)
+ S X=$E(XML,CPOS)
+"RTN","MXMLPRSE",87,0)
+ I X'?1A,"_:"'[X D:$G(ERN) ERROR(ERN,X) Q ""
+"RTN","MXMLPRSE",88,0)
+ Q $$NAMETKN(.ERN)
+"RTN","MXMLPRSE",89,0)
+ ; Parse name token
+"RTN","MXMLPRSE",90,0)
+ ; ERN=Error to signal if invalid (optional)
+"RTN","MXMLPRSE",91,0)
+NAMETKN(ERN) ;
+"RTN","MXMLPRSE",92,0)
+ N X,Y
+"RTN","MXMLPRSE",93,0)
+ D EPOS
+"RTN","MXMLPRSE",94,0)
+ F X=CPOS:1:LLEN+1 S Y=$E(XML,X) I Y'?1AN,".-_:"'[Y Q
+"RTN","MXMLPRSE",95,0)
+ S Y=$E(XML,CPOS,X-1),CPOS=X
+"RTN","MXMLPRSE",96,0)
+ I '$L(Y),$G(ERN) D ERROR(ERN,Y)
+"RTN","MXMLPRSE",97,0)
+ Q Y
+"RTN","MXMLPRSE",98,0)
+ ; Parse quote-enclosed value
+"RTN","MXMLPRSE",99,0)
+ ; ERF=If set, signal error if not found
+"RTN","MXMLPRSE",100,0)
+ ; FLG=Special flag: 0=attribute literal, 1=general entity literal
+"RTN","MXMLPRSE",101,0)
+ ; 2=parameter entity literal
+"RTN","MXMLPRSE",102,0)
+ ; Returns value less quotes with normalized whitespace
+"RTN","MXMLPRSE",103,0)
+VALUE(ERF,FLG) ;
+"RTN","MXMLPRSE",104,0)
+ N DLM,CHR,RTN,EXC
+"RTN","MXMLPRSE",105,0)
+ D WS()
+"RTN","MXMLPRSE",106,0)
+ S DLM=$S($$NEXT(QT):QT,$$NEXT("'"):"'",1:""),RTN="",FLG=+$G(FLG),EXC=$S(FLG=2:"",1:"<")
+"RTN","MXMLPRSE",107,0)
+ I DLM="" D:$G(ERF) EPOS,ERROR(11) Q RTN
+"RTN","MXMLPRSE",108,0)
+ F S CHR=$E(XML,CPOS) Q:DLM=CHR!(EXC[CHR)!EOD D
+"RTN","MXMLPRSE",109,0)
+ .I $$NEXT("") S RTN=RTN_$$CHENTITY
+"RTN","MXMLPRSE",110,0)
+ .E I 'FLG,$$NEXT("&") S RTN=RTN_$$ENTITY
+"RTN","MXMLPRSE",111,0)
+ .E S RTN=RTN_CHR,CPOS=CPOS+1
+"RTN","MXMLPRSE",112,0)
+ .;D:CPOS>LLEN READ
+"RTN","MXMLPRSE",113,0)
+ .D:(LLEN-CPOS)<50 READ ;P136
+"RTN","MXMLPRSE",114,0)
+ I DLM=CHR S CPOS=CPOS+1
+"RTN","MXMLPRSE",115,0)
+ E D EPOS,ERROR($S('$L(CHR):12,EXC[CHR:13,1:12)) Q ""
+"RTN","MXMLPRSE",116,0)
+ Q $$NMLWS(RTN)
+"RTN","MXMLPRSE",117,0)
+ ; Normalize whitespace
+"RTN","MXMLPRSE",118,0)
+ ; Note: used as input transform for Entity Catalog, so can't depend
+"RTN","MXMLPRSE",119,0)
+ ; on any environment variables.
+"RTN","MXMLPRSE",120,0)
+ ; TXT=Text to normalize
+"RTN","MXMLPRSE",121,0)
+ ; Returns text stripped of leading and trailing whitespace and with
+"RTN","MXMLPRSE",122,0)
+ ; imbedded contiguous whitespace reduced to single space.
+"RTN","MXMLPRSE",123,0)
+NMLWS(TXT,FG) ;
+"RTN","MXMLPRSE",124,0)
+ N Z,CRLF
+"RTN","MXMLPRSE",125,0)
+ S CRLF=$C(13,10)
+"RTN","MXMLPRSE",126,0)
+ ;Normalize CRLF to one SP first
+"RTN","MXMLPRSE",127,0)
+ F S Z=$F(TXT,CRLF) Q:'Z S TXT=$P(TXT,CRLF,1)_" "_$P(TXT,CRLF,2,999)
+"RTN","MXMLPRSE",128,0)
+ S TXT=$TR(TXT,$C(9,10,13,32)," ")
+"RTN","MXMLPRSE",129,0)
+ ;For CDATA or unk, this is where we should stop
+"RTN","MXMLPRSE",130,0)
+ Q:'$G(FG) TXT
+"RTN","MXMLPRSE",131,0)
+ F Z=1:1 Q:$E(TXT,Z)'=" "
+"RTN","MXMLPRSE",132,0)
+ S TXT=$E(TXT,Z,9999)
+"RTN","MXMLPRSE",133,0)
+ F Z=$L(TXT):-1 Q:$E(TXT,Z)'=" "
+"RTN","MXMLPRSE",134,0)
+ S TXT=$E(TXT,1,Z)
+"RTN","MXMLPRSE",135,0)
+ F Z=1:1:$L(TXT) D:$E(TXT,Z)=" "
+"RTN","MXMLPRSE",136,0)
+ .F Q:$E(TXT,Z+1)'=" " S $E(TXT,Z+1)=""
+"RTN","MXMLPRSE",137,0)
+ Q TXT
+"RTN","MXMLPRSE",138,0)
+ ; Process parameter entity if found
+"RTN","MXMLPRSE",139,0)
+DOPARAM F D WS() Q:EOD!'$$NEXT("%") I $$ENTITY(1)
+"RTN","MXMLPRSE",140,0)
+ Q
+"RTN","MXMLPRSE",141,0)
+ ; Resolve general/parameter/character entity
+"RTN","MXMLPRSE",142,0)
+ ; PARAM=1: parameter; PARAM=0: general or character (default)
+"RTN","MXMLPRSE",143,0)
+ENTITY(PARAM) ;
+"RTN","MXMLPRSE",144,0)
+ N NAME,APND
+"RTN","MXMLPRSE",145,0)
+ S PARAM=+$G(PARAM)
+"RTN","MXMLPRSE",146,0)
+ I CPOS+10>LLEN D READ ; VEN/SMH v2.1 - Read ahead for Entity if not enough in XML buffer.
+"RTN","MXMLPRSE",147,0)
+ I 'PARAM,$$NEXT("#") Q $$CHENTITY
+"RTN","MXMLPRSE",148,0)
+ S NAME=$S(PARAM:"%",1:"")_$$NAME(2)
+"RTN","MXMLPRSE",149,0)
+ Q:'$$NEXT(";",3) ""
+"RTN","MXMLPRSE",150,0)
+ ;Handle the common ones inline
+"RTN","MXMLPRSE",151,0)
+ S APND=$S(NAME="amp":"&",NAME="lt":"<",NAME="gt":">",NAME="quot":$C(34),NAME="apos":"'",1:"")
+"RTN","MXMLPRSE",152,0)
+ Q:$L(APND) APND
+"RTN","MXMLPRSE",153,0)
+ I $D(^TMP(ID,$J,"UNP",NAME)) D ERROR(40,NAME) Q ""
+"RTN","MXMLPRSE",154,0)
+ I '$D(^TMP(ID,$J,"ENT",NAME)) D ERROR(14,NAME) Q ""
+"RTN","MXMLPRSE",155,0)
+ S APND=$S(PARAM:" ",1:"")
+"RTN","MXMLPRSE",156,0)
+ D OPNDOC(^TMP(ID,$J,"ENT",NAME),APND,APND)
+"RTN","MXMLPRSE",157,0)
+ Q ""
+"RTN","MXMLPRSE",158,0)
+ ; Parse character entity reference
+"RTN","MXMLPRSE",159,0)
+ ; Returns character equivalent
+"RTN","MXMLPRSE",160,0)
+CHENTITY() ;
+"RTN","MXMLPRSE",161,0)
+ N DIGIT,BASE,DIGITS,VAL
+"RTN","MXMLPRSE",162,0)
+ S BASE=$S($$NEXT("x"):16,1:10),DIGITS="0123456789"_$S(BASE=16:"ABCDEF",1:""),VAL=0
+"RTN","MXMLPRSE",163,0)
+ F CPOS=CPOS:1:LLEN+1 Q:$$NEXT(";")!EOD D
+"RTN","MXMLPRSE",164,0)
+ .S DIGIT=$F(DIGITS,$$UP^XLFSTR($E(XML,CPOS)))-2,VAL=VAL*BASE+DIGIT
+"RTN","MXMLPRSE",165,0)
+ .D:DIGIT<0 ERROR(19)
+"RTN","MXMLPRSE",166,0)
+ I VAL<32,WS'[$C(VAL) D ERROR(19)
+"RTN","MXMLPRSE",167,0)
+ Q $C(VAL)
+"RTN","MXMLPRSE",168,0)
+ ; Set an entity value
+"RTN","MXMLPRSE",169,0)
+SETENT(NAME,VAL) ;
+"RTN","MXMLPRSE",170,0)
+ K ^TMP(ID,$J,"ENT",NAME)
+"RTN","MXMLPRSE",171,0)
+ S ^(NAME)=$NA(^(NAME)),^(NAME,1)=VAL
+"RTN","MXMLPRSE",172,0)
+ Q
+"RTN","MXMLPRSE",173,0)
+ ; Process all attributes
+"RTN","MXMLPRSE",174,0)
+ATTRIBS(ENAME,ATTR) ;
+"RTN","MXMLPRSE",175,0)
+ N TYP,MOD,DEF,ANAME
+"RTN","MXMLPRSE",176,0)
+ K ATTR
+"RTN","MXMLPRSE",177,0)
+ F Q:'$$ATTRIB(ENAME,.ATTR)
+"RTN","MXMLPRSE",178,0)
+ I OPTION["V" D
+"RTN","MXMLPRSE",179,0)
+ .S ANAME="$"
+"RTN","MXMLPRSE",180,0)
+ .F S ANAME=$O(^TMP(ID,$J,"ATT",ENAME,ANAME)) Q:'$L(ANAME) D
+"RTN","MXMLPRSE",181,0)
+ ..S TYP=^(ANAME),MOD=$P(TYP,"^",2),DEF=$P(TYP,"^",3,9999),TYP=+TYP
+"RTN","MXMLPRSE",182,0)
+ ..I MOD=1!(MOD=3),'$D(ATTR(ANAME)) D ERROR(36,ANAME) Q
+"RTN","MXMLPRSE",183,0)
+ ..I MOD=3,ATTR(ANAME)'=DEF D ERROR(37,ATTR(ANAME)) Q
+"RTN","MXMLPRSE",184,0)
+ ..I MOD=2,'$D(ATTR(ANAME)) Q
+"RTN","MXMLPRSE",185,0)
+ ..S:'$D(ATTR(ANAME)) ATTR(ANAME)=DEF
+"RTN","MXMLPRSE",186,0)
+ Q
+"RTN","MXMLPRSE",187,0)
+ ; Parse attribute=value sequence
+"RTN","MXMLPRSE",188,0)
+ ; ENAME=Element name to which attribute belongs
+"RTN","MXMLPRSE",189,0)
+ ; ATTR=Local array (by reference) to receive attribute value.
+"RTN","MXMLPRSE",190,0)
+ ; Format is ATTR("")=""
+"RTN","MXMLPRSE",191,0)
+ ; Returns 1 if successful, 0 if not.
+"RTN","MXMLPRSE",192,0)
+ATTRIB(ENAME,ATTR) ;
+"RTN","MXMLPRSE",193,0)
+ N ANAME
+"RTN","MXMLPRSE",194,0)
+ D READ,WS() ;p116
+"RTN","MXMLPRSE",195,0)
+ S ANAME=$$NAME
+"RTN","MXMLPRSE",196,0)
+ Q:ANAME="" 0
+"RTN","MXMLPRSE",197,0)
+ I $D(ATTR(ANAME)) D ERROR(4,ANAME) Q 0
+"RTN","MXMLPRSE",198,0)
+ D:'$D(^TMP(ID,$J,"ATT",ENAME,ANAME)) ERROR(29,ANAME)
+"RTN","MXMLPRSE",199,0)
+ D READ,WS() ;p116
+"RTN","MXMLPRSE",200,0)
+ Q:'$$NEXT("=",3) 0
+"RTN","MXMLPRSE",201,0)
+ D WS()
+"RTN","MXMLPRSE",202,0)
+ S ATTR(ANAME)=$$VALUE(1)
+"RTN","MXMLPRSE",203,0)
+ D CHKVAL^MXMLPRS1(ENAME,ANAME,ATTR(ANAME))
+"RTN","MXMLPRSE",204,0)
+ Q 1
+"RTN","MXMLPRSE",205,0)
+ ; Parse a processing instruction
+"RTN","MXMLPRSE",206,0)
+ ; Returns 1 if PI found, 0 if not.
+"RTN","MXMLPRSE",207,0)
+PI() N PNAME,ARGS,DONE
+"RTN","MXMLPRSE",208,0)
+ Q:'$$NEXT("") 0
+"RTN","MXMLPRSE",209,0)
+ S PNAME=$$NAME(2),ARGS=0
+"RTN","MXMLPRSE",210,0)
+ I $$UP^XLFSTR(PNAME)="XML" D ERROR(9) Q 0
+"RTN","MXMLPRSE",211,0)
+ D WS(1)
+"RTN","MXMLPRSE",212,0)
+ F S DONE=$F(XML,"?>",CPOS) D Q:DONE!EOD
+"RTN","MXMLPRSE",213,0)
+ .S ARGS=ARGS+1,ARGS(ARGS)=$E(XML,CPOS,$S(DONE:DONE-3,1:LLEN))
+"RTN","MXMLPRSE",214,0)
+ .S CPOS=$S(DONE:DONE,1:LLEN+1)
+"RTN","MXMLPRSE",215,0)
+ .D READ
+"RTN","MXMLPRSE",216,0)
+ I EOD D ERROR(7) Q 0
+"RTN","MXMLPRSE",217,0)
+ D CBK("PI",PNAME,.ARGS)
+"RTN","MXMLPRSE",218,0)
+ Q 1
+"RTN","MXMLPRSE",219,0)
+ ; Parse a comment
+"RTN","MXMLPRSE",220,0)
+ ; Returns 1 if comment found, 0 if not.
+"RTN","MXMLPRSE",221,0)
+COMMENT() Q $$PARSCT("