def build(self, xmlDoc, name=None): """Build the overall :class:`X12.parse.Message` parser. :param xmlDoc: a :class:`XMLParser` which has parsed the data, codes and message structure documents. :param name: Optional name of the Message to build; this will use the xid attribute provided in the XML if no overriding name is provided here. :returns: :class:`X12.parse.Message` parser. """ self.dataElements(xmlDoc) self.codes(xmlDoc) doc = xmlDoc.doc.documentElement assert doc.nodeType == DOM.Node.ELEMENT_NODE and doc.nodeName == "transaction" xid = doc.getAttribute('xid') desc = self.getChildTextValue(doc, "name") if name is None: name = xid self.log.info("Message %s: xid=%s desc=%s", name, xid, desc) self.top = Message(name, Properties(desc=desc)) for c in doc.childNodes: # Want to preserve the original XML order of <loop> and <segment> if c.nodeType != DOM.Node.ELEMENT_NODE: continue if c.nodeName == "loop": self.buildLoop(c, self.top) elif c.nodeName in ("name", ): pass # Already consumed this else: warnings.warn(XMLWarning("Unexpected %r" % (c, ))) self.log.warning("*** Unexpected %r", c) return self.top
def testBadLoop(self): """Can't include a Message within a Loop.""" self.assertRaises( StructureError, Loop, "name", Properties( desc="desc", req_sit="R", repeat="1"), Message("bad", Properties(desc="bad")))
class TestConvertPyx12(unittest.TestCase): """Test conversion of PyX12 source XML definitions. .. note:: The ORIGINAL 278.4010.X094.A1.xml definition was improperly nested. The 2000A, 2000B, 2000C, 2000D, 2000E, 2000F Loop structure was not flat; a failure to match the Situational 2000D segment means that are no more segments were available to match. Why no more? 2000E and 2000F are nested within 2010D - inexplicably. """ def setUp(self): raise unittest.SkipTest('Broken as of July 1, 2014') # a 278-13 - I think this is a referral response self.msg1 = """ISA*03*gjohnson2 *01*0000000000*ZZ*0000000Eliginet*ZZ*BLUECROSS BLUES*071015*0903*U*00401*000242835*0*P*:~GS*HI*0000000Eliginet*BLUECROSS BLUES*20071015*0903*241935*X*004010X094A1~ST*278*242835~BHT*0078*13*GXEDWLXQYKII*20071015*0903~HL*1**20*1~NM1*X3*2*BLUECROSS BLUESHIELD OF WESTERN NEW*****PI*55204~HL*2*1*21*1~NM1*1P*1*SHEIKH*ZIA****24*161590688~REF*ZH*000524454008~N3*4039 ROUTE 219*SUITE 102~N4*SALAMANCA*NY*14779~HL*3*2*22*1~HI*BF:706.1~NM1*IL*1*burton*amanda****MI*yjw88034076701~DMG*D8*19900815*U~HL*4*3*19*1~NM1*SJ*1*JAREMKO*WILLIAM****24*161482964~REF*ZH*000511127003~N3*2646 WEST STATE STREET*SUITE 405~N4*OLEAN*NY*147600000~HL*5*4*SS*0~TRN*1*1*9999955204~UM*SC*I*******Y~DTP*472*RD8*20071015-20080415~HSD*VS*30~SE*24*242835~GE*1*241935~IEA*1*000242835~""" bldParser = convertPyX12.ParserBuilder() xml = convertPyX12.XMLParser() xml.data(open("tests/map/dataele.xml")) xml.codes(open("tests/map/codes.xml")) #The 278 definition doesn't have the correct nested LOOP structure to parse xml.read(open("tests/map/278.4010.X094.A1.xml")) #This 278 definition seems to parse better. #xml.read( os.path.join( "test", "278.4010.X094.A1.xml" ) ) self.x12p = bldParser.build(xml) sql = SQLTableVisitor() self.x12p.visit(sql) self.sqlCode = sql.getSource() python = FlatPythonVisitor("parse_278") self.x12p.visit(python) self.pyCode = python.getSource() def testPythonOut(self): try: # Creates response parser, parse_278 exec self.pyCode except Exception, ex: logger.exception(self.pyCode) try: x12mssg = parse_278.unmarshall(self.msg1) except Exception, ex: logger.exception(self.pyCode) eltPunct, compPunct, segPunct, segments = Message.tokenize( self.msg1) logger.error(segments) raise
def testPythonOut( self ): try: # Creates response parser, parse_278 exec(self.pyCode) except Exception as ex: logger.exception( self.pyCode ) try: x12mssg= parse_278.unmarshall( self.msg1 ) except Exception as ex: logger.exception( self.pyCode ) eltPunct, compPunct, segPunct, segments= Message.tokenize(self.msg1) logger.error( segments ) raise # TODO: Assert something... print( "result" ) print( x12mssg )
def testPythonOut(self): try: # Creates response parser, parse_278 exec(self.pyCode) except Exception as ex: logger.exception(self.pyCode) try: x12mssg = parse_278.unmarshall(self.msg1) except Exception as ex: logger.exception(self.pyCode) eltPunct, compPunct, segPunct, segments = Message.tokenize( self.msg1) logger.error(segments) raise # TODO: Assert something... print("result") print(x12mssg)
codes=[u'0', u'1'] ) ), Element( u'ISA15', Properties(desc=u'I14', req_sit=u'R', data_type=(u'ID',u'1',u'1'), position=15, codes=[u'P', u'T'] ) ), Element( u'ISA16', Properties(desc=u'I15', req_sit=u'R', data_type=(u'AN',u'1',u'1'), position=16, codes=[] ) ), ), parsed_270_GS_LOOP, Segment( u'TA1', Properties(syntax='',req_sit=u'S',repeat=u'1',pos=u'020',desc=u'Interchange Acknowledgement'), Element( u'TA101', Properties(desc=u'I12', req_sit=u'R', data_type=(u'N0',u'9',u'9'), position=1, codes=[] ) ), Element( u'TA102', Properties(desc=u'I08', req_sit=u'R', data_type=(u'DT',u'6',u'6'), position=2, codes=[] ) ), Element( u'TA103', Properties(desc=u'I09', req_sit=u'R', data_type=(u'TM',u'4',u'4'), position=3, codes=[] ) ), Element( u'TA104', Properties(desc=u'I17', req_sit=u'R', data_type=(u'ID',u'1',u'1'), position=4, codes=[u'A', u'E', u'R'] ) ), Element( u'TA105', Properties(desc=u'I18', req_sit=u'R', data_type=(u'ID',u'3',u'3'), position=5, codes=[u'000', u'001', u'002', u'003', u'004', u'005', u'006', u'007', u'008', u'009', u'010', u'011', u'012', u'013', u'014', u'015', u'016', u'017', u'018', u'019', u'020', u'021', u'022', u'023', u'024', u'025', u'026', u'027', u'028', u'029', u'030', u'031'] ) ), ), Segment( u'IEA', Properties(syntax='',req_sit=u'R',repeat=u'1',pos=u'030',desc=u'Interchange Control Trailer'), Element( u'IEA01', Properties(desc=u'I16', req_sit=u'R', data_type=(u'N0',u'1',u'5'), position=1, codes=[] ) ), Element( u'IEA02', Properties(desc=u'I12', req_sit=u'R', data_type=(u'N0',u'9',u'9'), position=2, codes=[] ) ), ), ) parsed_270 = Message( u'270', Properties(desc=u'HIPAA Health Care Eligibility Inquiry X092A1-270'), parsed_270_ISA_LOOP, )
parse_278 = Message( "278", Properties(desc="HIPAA Health Care Services Review: Request X094A1-278", ), Loop( "ISA", Properties( desc="ISA", req_sit="R", repeat="1", ), Segment("ISA", Properties()), Loop( "GS", Properties( desc="GS", req_sit="R", repeat="1", ), Segment("GS", Properties()), Loop( "ST", Properties( desc="ST", req_sit="R", repeat="1", ), Segment( "ST", Properties(qual=(1, "278"), desc="Transaction Set Header", req_sit="R", repeat='1'), Element("ST01", Properties(position=1, codes=["278"]))), Segment( "BHT", Properties(desc="Beginning of Hierarchical Transaction", req_sit="R", repeat='1')), loop2000A, loop2000B, loop2000C, loop2000D, loop2000E, loop2000F, ), Loop("SE", Properties( desc="SE", req_sit="R", repeat="1", ), Segment("SE", Properties())), ), Loop("GE", Properties( desc="GE", req_sit="R", repeat="1", ), Segment("GE", Properties())), ), Loop( "IEA", Properties(desc="IEA", req_sit="R", repeat="1"), Segment("IEA", Properties()), ), )
ISALoop = Loop( u'ISA_LOOP', Properties( position=u'0010', looptype=u'explicit', repeat=u'>1', req_sit=u'R', desc=u'Interchange Control Header', ), standardSegment.isa, GSLoop, ) ControlParser = Message( u'ASC X12 Interchange Control Structure', Properties(desc=u'ASC X12 Control Structure', ), ISALoop, ) def parse_control_headers(x12_contents): """Parse only the control headers of an X12 message. This parses the three outer control headers of the given X12 message: * Interchange Control (ISA) * Functional Group (GS) * Transaction Set (ST). These can be used to identify the X12 versions and transaction set types contained in the message.
codes=[u'0', u'1'] ) ), Element( u'ISA15', Properties(desc=u'I14', req_sit=u'R', data_type=(u'ID',u'1',u'1'), position=15, codes=[u'P', u'T'] ) ), Element( u'ISA16', Properties(desc=u'I15', req_sit=u'R', data_type=(u'AN',u'1',u'1'), position=16, codes=[] ) ), ), parsed_277_GS_LOOP, Segment( u'TA1', Properties(syntax='',req_sit=u'S',repeat=u'1',pos=u'020',desc=u'Interchange Acknowledgement'), Element( u'TA101', Properties(desc=u'I12', req_sit=u'R', data_type=(u'N0',u'9',u'9'), position=1, codes=[] ) ), Element( u'TA102', Properties(desc=u'I08', req_sit=u'R', data_type=(u'DT',u'6',u'6'), position=2, codes=[] ) ), Element( u'TA103', Properties(desc=u'I09', req_sit=u'R', data_type=(u'TM',u'4',u'4'), position=3, codes=[] ) ), Element( u'TA104', Properties(desc=u'I17', req_sit=u'R', data_type=(u'ID',u'1',u'1'), position=4, codes=[u'A', u'E', u'R'] ) ), Element( u'TA105', Properties(desc=u'I18', req_sit=u'R', data_type=(u'ID',u'3',u'3'), position=5, codes=[u'000', u'001', u'002', u'003', u'004', u'005', u'006', u'007', u'008', u'009', u'010', u'011', u'012', u'013', u'014', u'015', u'016', u'017', u'018', u'019', u'020', u'021', u'022', u'023', u'024', u'025', u'026', u'027', u'028', u'029', u'030', u'031'] ) ), ), Segment( u'IEA', Properties(syntax='',req_sit=u'R',repeat=u'1',pos=u'030',desc=u'Interchange Control Trailer'), Element( u'IEA01', Properties(desc=u'I16', req_sit=u'R', data_type=(u'N0',u'1',u'5'), position=1, codes=[] ) ), Element( u'IEA02', Properties(desc=u'I12', req_sit=u'R', data_type=(u'N0',u'9',u'9'), position=2, codes=[] ) ), ), ) parsed_277 = Message( u'277', Properties(desc=u'HIPAA Health Care Claim Status Response X093A1-277'), parsed_277_ISA_LOOP, )
])), ), Segment( u'IEA', Properties(syntax='', req_sit=u'R', repeat=u'1', pos=u'030', desc=u'Interchange Control Trailer'), Element( u'IEA01', Properties(desc=u'I16', req_sit=u'R', data_type=(u'N0', u'1', u'5'), position=1, codes=[])), Element( u'IEA02', Properties(desc=u'I12', req_sit=u'R', data_type=(u'N0', u'9', u'9'), position=2, codes=[])), ), ) parsed_841 = Message( u'841', Properties(desc=u'HIPAA Related Code Lists'), parsed_841_ISA_LOOP, )