Пример #1
0
 def setUp( self ):
     self.segments1= [ ['ST', '278', '242835'] ]
     self.segments2= [ ['ST', '279', '242835'] ]
     self.parserQual= Segment( "ST", Properties( qual=(1,"278"), desc="ST", req_sit="R" ),
         Element( "ST01", Properties(position=1,codes=["278"]) ),
         )
     self.parserNonQual= Segment( "ST", Properties( desc="ST", req_sit="R" ) )
Пример #2
0
 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")))
Пример #3
0
 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
Пример #4
0
def buildSegment(name, desc, fieldText):
    """Convert a block of text to a Segment definition.
    The block of text has one Element defined on each line.
    The Element definition is an Element name, one or more spaces, and the
    element description.

    :param name: the name of the segment
    :param desc: the description of the segment
    :param fieldText: a block of text, with one Element name
        and description per line.
    :returns: :class:`X12.parse.Segment` definition
    """
    segment = Segment(name, Properties(desc=desc))
    for line in filter(None, fieldText.splitlines()):
        name, description = line.strip().split(None, 1)
        element = Element(name, Properties(desc=description, codes=[]))
        segment.append(element)
    return segment
Пример #5
0
def buildSegment(name, desc, fieldText):
    """Convert a block of text to a Segment definition.
    The block of text has one Element defined on each line.
    The Element definition is an Element name, one or more spaces, and the
    element description.
    
    :param name: the name of the segment
    :param desc: the description of the segment
    :param fieldText: a block of text, with one Element name and description per line.
    :returns: :class:`X12.parse.Segment` definition
    """
    theSeg = Segment(name, Properties(desc=desc))
    for line in fieldText.splitlines():
        clean = line.strip()
        eltName, space, eltDesc = clean.partition(" ")
        theElt = Element(eltName, Properties(desc=eltDesc))
        theSeg.append(theElt)
    return theSeg
Пример #6
0
    def buildComposite(self, compositeNode, context, nesting=0):
        """Build a Composite from a list of sub-Elements.

        Note that the ISA segment provides the Component Element Separator in ISA16.

        Composites are tricky.  We have two choices.

            1.  Treat them as just a sequence of Elements -- which they
                are for RDBMS purposes.  However, this makes compliance
                checking hard, since we have to look inside the composite.
                We have to turn off "match" for each Element of the Composite,
                otherwise, we won't be able to look into the segment data
                properly.

            2.  Treat them as a subclass of Elements -- which is a lot of
                fooling around to support a few compliance checks.  We have to
                provide a composite match function and we have to make use
                of punctuation in the ISA segment for sub-parsing each Composite when we
                finally figure out what the Segment and Elements.

        :param compositeNode: a :mod:`xml.dom` Element with a name of :samp:`composite`
        :param context: The Segment which contains this Composite
        :param nesting: The current nesting level used to indent the log messages.
        """
        assert compositeNode.nodeType == DOM.Node.ELEMENT_NODE and compositeNode.nodeName == "composite"
        name = self.getChildTextValue(compositeNode, "name")
        usage = self.getChildTextValue(compositeNode, "usage")
        seq = self.getChildTextValue(compositeNode, "seq")
        data_ele = self.getChildTextValue(compositeNode, "data_ele")
        refdes = self.getChildTextValue(compositeNode, "refdes")
        repeat = self.getChildTextValue(compositeNode,
                                        "repeat")  # TODO add support
        self.log.debug(
            "%*sComposite name %r usage %r seq %r data_ele %r refdes %r",
            nesting * 2, '', name, usage, seq, data_ele, refdes)
        theComposite = Composite(
            data_ele,
            Properties(desc=name,
                       req_sit=usage,
                       seq=seq,
                       refdes=refdes,
                       repeat=repeat))
        for c in compositeNode.childNodes:
            # Want to preserve the original XML order of <element>
            if c.nodeType != DOM.Node.ELEMENT_NODE: continue
            if c.nodeName == "element":
                self.buildElement(c, theComposite, nesting + 1)
            elif c.nodeName in ("name", "usage", "seq", "data_ele", 'refdes',
                                'repeat'):
                pass  # already consumed
            else:
                warnings.warn(XMLWarning("Unexpected %r" % (c, )))
                self.log.warning("*** Unexpected %r", c)
        context.append(theComposite)
Пример #7
0
    def buildLoop(self, loopNode, context, nesting=0):
        """Loop contains Segments and Loops.
        Empty Loops create a warning, and are dropped.
        
        :param loopNode: a :mod:`xml.dom` Element with a name of :samp:`loop`
        :param context: The Loop which contains this Loop or Segment.
        :param nesting: The current nesting level used to indent the log messages.
        """
        assert loopNode.nodeType == DOM.Node.ELEMENT_NODE and loopNode.nodeName == "loop"
        loopXid = loopNode.getAttribute('xid')
        loopType = loopNode.getAttribute('type')
        name = self.getChildTextValue(loopNode, "name")
        usage = self.getChildTextValue(loopNode, "usage")
        pos = self.getChildTextValue(loopNode, "pos")
        repeat = self.getChildTextValue(loopNode, "repeat")
        self.log.debug(
            "%*sLoop xid %r type %r: name %r usage %r pos %r repeat %r",
            nesting * 2, '', loopXid, loopType, name, usage, pos, repeat)
        theLoop = Loop(
            loopXid,
            Properties(desc=name,
                       req_sit=usage,
                       position=pos,
                       repeat=repeat,
                       looptype=loopType),
        )

        for c in loopNode.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, theLoop, nesting + 1)
            elif c.nodeName == "segment":
                self.buildSegment(c, theLoop, nesting + 1)
            elif c.nodeName in (
                    "name",
                    "usage",
                    "pos",
                    "repeat",
            ):
                pass  # already consumed
            else:
                warnings.warn(XMLWarning("Unexpected %r" % (c, )))
                self.log.warning("*** Unexpected %r", c)
        if len(theLoop.structure) == 0:
            warnings.warn(EmptyLoopWarning("Empty Loop %r" % (theLoop, )))
            # optimize this out of existence
        else:
            context.append(theLoop)
Пример #8
0
    def buildSegment(self, segmentNode, context, nesting=0):
        """Segment contains Elements and Composites.
        
        :param segmentNode: a :mod:`xml.dom` Element with a name of :samp:`segment`
        :param context: The Loop which contains this Segment.
        :param nesting: The current nesting level used to indent the log messages.
        """
        assert segmentNode.nodeType == DOM.Node.ELEMENT_NODE and segmentNode.nodeName == "segment"
        segXid = segmentNode.getAttribute('xid')
        name = self.getChildTextValue(segmentNode, "name")
        usage = self.getChildTextValue(segmentNode, "usage")
        pos = self.getChildTextValue(segmentNode, "pos")
        max_use = self.getChildTextValue(segmentNode, "max_use")
        syntax = self.getChildTextValue(segmentNode, "syntax")
        self.log.debug(
            "%*sSegment xid %r: name %r usage %r pos %r max_use %r syntax %r",
            nesting * 2, '', segXid, name, usage, pos, max_use, syntax)
        theSegment = Segment(
            segXid,
            Properties(desc=name,
                       req_sit=usage,
                       position=pos,
                       repeat=max_use,
                       syntax=syntax),
        )

        for c in segmentNode.childNodes:
            # Want to preserve the original XML order of <element> and <composite>
            if c.nodeType != DOM.Node.ELEMENT_NODE: continue
            if c.nodeName == "element":
                self.buildElement(c, theSegment, nesting + 1)
            elif c.nodeName == "composite":
                self.buildComposite(c, theSegment, nesting + 1)
            elif c.nodeName in (
                    "name",
                    "usage",
                    "pos",
                    "max_use",
                    "syntax",
            ):
                pass  # already consumed
            else:
                warnings.warn(XMLWarning("Unexpected %r" % (c, )))
                self.log.warning("*** Unexpected %r", c)
        context.append(theSegment)
Пример #9
0
#
# Generated by TigerShark.tools.convertPyX12 on 2012-10-03 14:38:27.454816
#
from tigershark.X12.parse import Message, Loop, Segment, Composite, Element, Properties
parsed_270_HEADER = Loop( u'HEADER', Properties(looptype=u'wrapper',repeat=u'1',pos=u'015',req_sit=u'R',desc=u'Table 1 - Header'), 
Segment( u'BHT', Properties(syntax='',req_sit=u'R',repeat=u'1',pos=u'020',desc=u'Beginning of Hierarchical Transaction'),
  Element( u'BHT01', Properties(desc=u'Hierarchical Structure Code', req_sit=u'R', data_type=(u'ID',u'4',u'4'), position=1,
    codes=[u'0022'] ) ),
  Element( u'BHT02', Properties(desc=u'Transaction Set Purpose Code', req_sit=u'R', data_type=(u'ID',u'2',u'2'), position=2,
    codes=[u'01', u'13', u'36'] ) ),
  Element( u'BHT03', Properties(desc=u'Reference Identification', req_sit=u'S', data_type=(u'AN',u'1',u'50'), position=3,
    codes=[] ) ),
  Element( u'BHT04', Properties(desc=u'Date', req_sit=u'R', data_type=(u'DT',u'8',u'8'), position=4,
    codes=[] ) ),
  Element( u'BHT05', Properties(desc=u'Time', req_sit=u'R', data_type=(u'TM',u'4',u'8'), position=5,
    codes=[] ) ),
  Element( u'BHT06', Properties(desc=u'Transaction Type Code', req_sit=u'S', data_type=(u'ID',u'2',u'2'), position=6,
    codes=[u'RT', u'RU'] ) ),
),
)
parsed_270_2100A = Loop( u'2100A', Properties(looptype='',repeat=u'1',pos=u'030',req_sit=u'R',desc=u'Information Source Name'), 
Segment( u'NM1', Properties(syntax='',req_sit=u'R',repeat=u'1',pos=u'030',desc=u'Information Source Name'),
  Element( u'NM101', Properties(desc=u'Entity Identifier Code', req_sit=u'R', data_type=(u'ID',u'2',u'3'), position=1,
    codes=[u'2B', u'36', u'GP', u'P5', u'PR'] ) ),
  Element( u'NM102', Properties(desc=u'Entity Type Qualifier', req_sit=u'R', data_type=(u'ID',u'1',u'1'), position=2,
    codes=[u'1', u'2'] ) ),
  Element( u'NM103', Properties(desc=u'Name Last or Organization Name', req_sit=u'S', data_type=(u'AN',u'1',u'60'), position=3,
    codes=[] ) ),
  Element( u'NM104', Properties(desc=u'Name First', req_sit=u'S', data_type=(u'AN',u'1',u'35'), position=4,
    codes=[] ) ),
  Element( u'NM105', Properties(desc=u'Name Middle', req_sit=u'S', data_type=(u'AN',u'1',u'25'), position=5,
Пример #10
0
    def buildElement(self, elementNode, context, nesting=0):
        """Element is the fundamental piece of data in a Segment or Composite.
        Elements can have code definitions or can reference external code
        definitions.
        
        ..  todo:: XXX - Use external code definitions.
        
        :param elementNode: a :mod:`xml.dom` Element with a name of :samp:`element`
        :param context: The Segment or Composite which contains this Element
        :param nesting: The current nesting level used to indent the log messages.
        """
        assert elementNode.nodeType == DOM.Node.ELEMENT_NODE and elementNode.nodeName == "element"
        eltXid = elementNode.getAttribute('xid')
        name = self.getChildTextValue(elementNode, "name")
        usage = self.getChildTextValue(elementNode, "usage")
        seq = self.getChildTextValue(elementNode, "seq")
        data_ele = self.getChildTextValue(elementNode, "data_ele")
        repeat = self.getChildTextValue(elementNode,
                                        "repeat")  # TODO add support
        self.log.debug("%*sElement id %r name %r usage %r seq %r data_ele %r",
                       nesting * 2, '', eltXid, name, usage, seq, data_ele)
        if not self.dataDictionary.has_key(data_ele):
            warnings.warn(
                UnknownElementWarning("No Data Element %r %r %r" % (
                    eltXid,
                    data_ele,
                    name,
                )))
            data_type_tuple = (None, None, None)
        else:
            name, data_type_tuple = self.dataDictionary[data_ele]

        codes = []
        for c in elementNode.childNodes:
            if c.nodeType != DOM.Node.ELEMENT_NODE: continue
            if c.nodeName == "valid_codes":
                if c.getAttribute("external") != "":
                    pass  # reference to codes.xml codes
                    # XXX - Handle external code list
                    warnings.warn(Extension("External Codes Not Implemented"))
                else:
                    codes = self.getValidCodes(c)
            elif c.nodeName in ("name", "usage", "seq", "data_ele", 'repeat'):
                pass  # already consumed
            else:
                warnings.warn(XMLWarning("Unexpected %r" % (c, )))
                self.log.warning("*** Unexpected %r", c)

        theElement = Element(
            eltXid,
            Properties(
                desc=name,
                req_sit=usage,
                seq=seq,
                data_ele=data_ele,
                data_type=data_type_tuple,
                codes=codes,
                repeat=repeat,
            ))

        if self.dataDictionary.has_key(data_ele) and len(codes) != 0:
            #self.log2.debug( "Segment Qual Parameter? %r %r", self.dataDictionary[data_ele], codes )
            pass

        context.append(theElement)
Пример #11
0
#!/usr/bin/env python
# EXAMPLE IMPLEMENTATION - 278 Request Parser
from tigershark.X12.parse import Message
from tigershark.X12.parse import Loop
from tigershark.X12.parse import Segment
from tigershark.X12.parse import Composite
from tigershark.X12.parse import Element
from tigershark.X12.parse import Properties

loop2000A = Loop(
    "2000A",
    Properties(
        desc="2000A",
        req_sit="R",
        repeat="1",
    ),
    Segment(
        "HL",
        Properties(qual=(3, "20"),
                   desc="Utilization Management Organization (UMO) Level",
                   req_sit="R",
                   repeat="1"),
        Element("HL03", Properties(position=3, codes=["20"]))),
    Loop(
        "2010A",
        Properties(
            desc="2010A",
            req_sit="R",
            repeat=">1",
        ),
        Segment(
Пример #12
0
        for parser in get_parsers(self.transaction_set_id, self.version_tuple):
            try:
                return parser.unmarshall(x12_contents, **kwargs)
            except ParseError:
                continue
        else:
            # Let the last parser raise.
            return parser.unmarshall(x12_contents, **kwargs)


STLoop = Loop(
    u'ST_LOOP',
    Properties(
        position=u'0200',
        looptype=u'explicit',
        repeat=u'>1',
        req_sit=u'R',
        desc=u'Transaction Set Header',
    ),
    standardSegment.st,
)

GSLoop = Loop(
    u'GS_LOOP',
    Properties(
        position=u'0200',
        looptype=u'explicit',
        repeat=u'>1',
        req_sit=u'R',
        desc=u'Functional Group Header',
    ),
Пример #13
0
#
# Generated by TigerShark.tools.convertPyX12 on 2012-07-10 16:29:58.460993
#
from tigershark.X12.parse import Message, Loop, Segment, Composite, Element, Properties
parsed_277_HEADER = Loop( u'HEADER', Properties(looptype=u'wrapper',repeat=u'1',pos=u'015',req_sit=u'R',desc=u'Table 1 - Header'),
Segment( u'BHT', Properties(syntax='',req_sit=u'R',repeat=u'1',pos=u'020',desc=u'Beginning of Hierarchical Transaction'),
  Element( u'BHT01', Properties(desc=u'Hierarchical Structure Code', req_sit=u'R', data_type=(u'ID',u'4',u'4'), position=1,
    codes=[u'0010'] ) ),
  Element( u'BHT02', Properties(desc=u'Transaction Set Purpose Code', req_sit=u'R', data_type=(u'ID',u'2',u'2'), position=2,
    codes=[u'08'] ) ),
  Element( u'BHT03', Properties(desc=u'Reference Identification', req_sit=u'R', data_type=(u'AN',u'1',u'50'), position=3,
    codes=[] ) ),
  Element( u'BHT04', Properties(desc=u'Date', req_sit=u'R', data_type=(u'DT',u'8',u'8'), position=4,
    codes=[] ) ),
  Element( u'BHT05', Properties(desc=u'Time', req_sit=u'N', data_type=(u'TM',u'4',u'8'), position=5,
    codes=[] ) ),
  Element( u'BHT06', Properties(desc=u'Transaction Type Code', req_sit=u'R', data_type=(u'ID',u'2',u'2'), position=6,
    codes=[u'DG'] ) ),
),
)
parsed_277_2100A = Loop( u'2100A', Properties(looptype='',repeat=u'>1',pos=u'050',req_sit=u'R',desc=u'Payer Name'),
Segment( u'NM1', Properties(syntax='',req_sit=u'R',repeat=u'1',pos=u'050',desc=u'Payer Name'),
  Element( u'NM101', Properties(desc=u'Entity Identifier Code', req_sit=u'R', data_type=(u'ID',u'2',u'3'), position=1,
    codes=[u'PR'] ) ),
  Element( u'NM102', Properties(desc=u'Entity Type Qualifier', req_sit=u'R', data_type=(u'ID',u'1',u'1'), position=2,
    codes=[u'2'] ) ),
  Element( u'NM103', Properties(desc=u'Name Last or Organization Name', req_sit=u'R', data_type=(u'AN',u'1',u'60'), position=3,
    codes=[] ) ),
  Element( u'NM104', Properties(desc=u'Name First', req_sit=u'N', data_type=(u'AN',u'1',u'35'), position=4,
    codes=[] ) ),
  Element( u'NM105', Properties(desc=u'Name Middle', req_sit=u'N', data_type=(u'AN',u'1',u'25'), position=5,
Пример #14
0
#!/usr/bin/env python
from tigershark.X12.parse import Message
from tigershark.X12.parse import Loop
from tigershark.X12.parse import Segment
from tigershark.X12.parse import Composite
from tigershark.X12.parse import Element
from tigershark.X12.parse import Properties

parse_278 = Message( '278', Properties(desc='278'),
  Loop( 'ISA', Properties(req_sit='R',repeat='1',desc='ISA'),
    Segment( 'ISA', Properties(),
    Loop( 'GS', Properties(req_sit='R',repeat='1',desc='GS'),
      Segment( 'GS', Properties(),
      Loop( 'ST', Properties(req_sit='R',repeat='1',desc='ST'),
        Segment( 'ST', Properties(qual=(1, '278'),req_sit='R',repeat=1,desc='Transaction Set Header'),
        Segment( 'BHT', Properties(req_sit='R',repeat=1,desc='Beginning of Hierarchical Transaction'),
        Loop( '2000A', Properties(req_sit='R',repeat='1',desc='2000A'),
          Segment( 'HL', Properties(qual=(3, '20'),req_sit='R',repeat='1',desc='Utilization Management Organization (UMO) Level'),
          Loop( '2010A', Properties(req_sit='R',repeat='>1',desc='2010A'),
            Segment( 'NM1', Properties(qual=(1, 'X3'),req_sit='R',repeat='1',desc='Utilization Management Organization (UMO) Name'),
          ),
        ),
        Loop( '2000B', Properties(req_sit='R',repeat='1',desc='2000B'),
          Segment( 'HL', Properties(qual=(3, '21'),req_sit='R',repeat='1',desc='Requester Level'),
          Loop( '2010B', Properties(req_sit='R',repeat='>1',desc='2010B'),
            Segment( 'NM1', Properties(qual=(1, ('1P', 'FA')),req_sit='R',repeat='1',desc='Requester Name'),
            Segment( 'REF', Properties(req_sit='S',repeat='8',desc='Requester Supplemental Identification'),
            Segment( 'N3', Properties(req_sit='S',repeat='1',desc='Requester Address'),
            Segment( 'N4', Properties(req_sit='S',repeat='1',desc='Requester City/State/ZIP Code'),
            Segment( 'PER', Properties(req_sit='S',repeat='1',desc='Requester Contact Information'),
            Segment( 'PRV', Properties(req_sit='S',repeat='1',desc='Requester Provider Information'),
Пример #15
0
#
# Generated by TigerShark.tools.convertPyX12 on 2012-07-10 16:30:03.879137
#
from tigershark.X12.parse import Message, Loop, Segment, Composite, Element, Properties
parsed_841_1100 = Loop(
    u'1100',
    Properties(looptype='',
               repeat=u'>1',
               pos=u'040',
               req_sit=u'R',
               desc=u'Code List Source'),
    Segment(
        u'N1',
        Properties(syntax=u'R0203 P0304',
                   req_sit=u'S',
                   repeat=u'1',
                   pos=u'120',
                   desc=u'Code List Source'),
        Element(
            u'N101',
            Properties(desc=u'Entity Identifier Code',
                       req_sit=u'R',
                       data_type=(u'ID', u'2', u'3'),
                       position=1,
                       codes=[u'0F'])),
        Element(
            u'N102',
            Properties(desc=u'Name',
                       req_sit=u'R',
                       data_type=(u'AN', u'1', u'60'),
                       position=2,