1

Crossposted at http://pyparsing.wikispaces.com/message/view/home/49765026

I am working on a parsing project where I need to inject some manually created parseresults into a parsed token. I have attached a parseaction to the appropriate place in my code, and I seem to have succeeded in creating a custom made parseresult to add back into my larger grammer. dump() and asxml() seem to output correctly, but other parts of my code (trying to access the created results by name) have issues. I can access by list position, but not assigned name. It is entirely possible that my limited python knowledge is messing me up somewhere, but since I have not been able to find an example of creating a parseresults quite this way I thought I would start here. Here is my parseresults creation code. tripHeaderCustomFields is attached as a parseaction. If a particular value is parsed (ie. "TripCode") then some custom parseresults are created and added back in to the final result.

If anyone has tried to create manual parseresults like this, could you please look over my code and tell me if you see any glaring problems? It took hours of trial and error to get this version to work, and I would not be surprised if there is a better or more correct way.

def addCustomField( self, group, name, datatype, value ):
    """
    custom fields:
    Group: ie, specific airline or category - "USAir, "general"
    Name: name of field, ie "linecheck", "Medical", "Deadhead", "IV Pay"
    DataType: string, int, date, time
    Value: value of field, ie. "checked by joe shmo, #2345", or "1st class medical - bryman"
    """
    #TODO: Need to ask for help, some logic problem somewhere. loosing string name somewhere, but xml prints ok!


    prGroup = ParseResults( group, self.NAME.CFGROUP )
    prName = ParseResults( name, self.NAME.CFNAME )
    prDataType = ParseResults( datatype, self.NAME.CFDATATYPE )
    prValue = ParseResults( value, self.NAME.CFVAULE )

    prList = ParseResults( [] )
    prList += prGroup
    prList += prName
    prList += prDataType
    prList += prValue

    customField = ParseResults( [prList], self.NAME.CUSTOMFIELD )


    return customField


def tripHeaderCustomFields( self, tokens ):
    parseSegment = tokens
    if "TripCode" in parseSegment:
        customField = self.addCustomField( "USAir", "PairingCode", "String", parseSegment["TripCode"] )
        if self.NAME.CUSTOMFIELDS in parseSegment:
            parseSegment[self.NAME.CUSTOMFIELDS] += customField
        else :
            parseSegment += ParseResults( [customField], self.NAME.CUSTOMFIELDS )
    if "Charter" in parseSegment[self.NAME.EFFECTIVEDOWS]:
        customField = self.addCustomField( "USAir", "Charter", "Boolean", "True" )
        if self.NAME.CUSTOMFIELDS in parseSegment:
            parseSegment[self.NAME.CUSTOMFIELDS] += customField
        else :
            parseSegment += ParseResults( [customField], self.NAME.CUSTOMFIELDS )
    return tokens

returns a seemingly correct token, 

     <CustomFields>
         <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
           <Value>True</Value>
         </CustomField>
         <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
            <Value>True</Value>
          </CustomField>
      </CustomFields>

that goes into a bigger result:

<Trip>
    <TripNumber>8510</TripNumber>
    <EffectiveDOWs>
      <EXCPT>EXCPT</EXCPT>
      <DayOfWeek>MO</DayOfWeek>
      <DayOfWeek>TH</DayOfWeek>
      <DayOfWeek>FR</DayOfWeek>
    </EffectiveDOWs>
    <ReportTime>
      <Hours>21</Hours>
      <Minutes>40</Minutes>
    </ReportTime>
    <TripCode>N</TripCode>
    <EffectiveDateStart>
      <Month>APR</Month>
      <Day>02</Day>
    </EffectiveDateStart>
    <EffectiveDateEnd>
      <Month>APR</Month>
      <Day>27</Day>
    </EffectiveDateEnd>
    <CustomFields>
      <CustomField>
        <Group>USAir</Group>
        <Name>PairingCode</Name>
        <DataType>String</DataType>
        <Value>N</Value>
      </CustomField>
    </CustomFields>
    <RequiredCrew>
      <Captain>1</Captain>
      <FO>1</FO>
    </RequiredCrew>

    .....snip....

</Trip>
Chad Lowe
  • 721
  • 1
  • 6
  • 12
  • plz Chad read my question http://stackoverflow.com/questions/11696338/adding-external-information-to-paeseresults-before-return – Diaa Fayed Jul 28 '12 at 22:51
  • Pyparsing is no longer hosted on wikispaces.com. Go to https://github.com/pyparsing/pyparsing – PaulMcG Aug 27 '18 at 12:58

1 Answers1

1

I have reworked my custom ParseResults code, and it now works as expected. I wish I had thought of doing it this way the first time, as it was much easier to figure out. :) I do tend to reinvent the wheel... tripHeaderCustomFields is attached as a ParseAction, and the new ParseResults are added to the parent ParseResults.

This solves the mysterious problem I had with accessing the customField items by name. I am sure it was caused by my not really understanding how the parse results are created behind the scenes, so this works out much better for me.

def tripHeaderCustomFields( self, tokens ):
    parseSegment = tokens
    if "TripCode" in parseSegment:
        customField = self.addCustomField( "USAir", "PairingCode", "String", parseSegment["TripCode"], parseSegment )
    if "Charter" in parseSegment[self.NAME.EFFECTIVEDOWS]:
        customField = self.addCustomField( "USAir", "Charter", "Boolean", "True", parseSegment )

def buildCustomFieldString( self, group, name, datatype, value ):
    #TODO: replace any stray "|" that might be in input strings

    text = group + "|" + name + "|" + datatype + "|" + value
    return text

def addCustomField( self, group, name, datatype, value, token ):
    """
    custom fields:
    Group: ie, specific airline or category - "USAir, "general"
    Name: name of field, ie "linecheck", "Medical", "Deadhead", "IV Pay"
    DataType: string, int, date, time
    Value: value of field, ie. "checked by joe shmo, #2345", or "1st class medical - bryman"
       <CustomFields>
          <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
            <Value>True</Value>
          </CustomField>
          <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
            <Value>True</Value>
          </CustomField>
        </CustomFields>
    """
    pGroup = Word( alphanums )( self.NAME.CFGROUP )
    pName = Word( alphanums )( self.NAME.CFNAME )
    pDatatype = Word( alphanums )( self.NAME.CFDATATYPE )
    pValue = Word( alphanums )( self.NAME.CFVAULE )
    delim = Suppress( "|" )
    customField = Group( pGroup + delim + pName + delim + pDatatype + delim + pValue )( self.NAME.CUSTOMFIELD )
    text = self.buildCustomFieldString( group, name, datatype, value )
    if self.NAME.CUSTOMFIELDS in token:
        token[self.NAME.CUSTOMFIELDS] += customField.parseString( text )
    else :
        token += Group( customField )( self.NAME.CUSTOMFIELDS ).parseString( text )
Chad Lowe
  • 721
  • 1
  • 6
  • 12