Module expandais
[hide private]
[frames] | no frames]

Source Code for Module expandais

  1  #!/usr/bin/env python 
  2   
  3  __version__ = '$Revision: 4820 $'.split()[1] 
  4  __date__ = '$Date: 2006-09-28 12:11:51 -0400 (Thu, 28 Sep 2006) $'.split()[1] 
  5  __author__ = 'Kurt Schwehr' 
  6   
  7  __doc__=''' 
  8  Expand structs in ais xml to include-struct elements while applying name mangling 
  9   
 10  @requires: U{lxml<http://codespeak.net/lxml/>} 
 11  @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3 
 12   
 13  @author: '''+__author__+''' 
 14  @version: ''' + __version__ +''' 
 15  @copyright: 2006 
 16  @var __date__: Date of last svn commit 
 17  @undocumented: __version__ __author__ __doc__ myparser 
 18  @since: 2006-Sep-26 
 19  @status: under development 
 20  @organization: U{CCOM<http://ccom.unh.edu/>} 
 21   
 22   
 23  @license: Restricted while in development to NOAA and USCG. 
 24  ''' 
 25   
 26  import sys 
 27  from lxml import etree  
 28   
29 -def getPos(parent,child):
30 ''' 31 Return the position number of the child node. It seems like this 32 really should be a part of the element tree interface. Perhaps 33 I overlooked it. 34 ''' 35 for i in range(len(parent)): 36 if parent[i]==child: return i 37 return None
38 39
40 -def expandAis(inET,verbose=False):
41 ''' 42 Replace each include-struct with the structure. This code is not 43 pretty, but it seems to work. The include-struct name is 44 prepended to each field name within the struct. The 45 include-struct description is also added to before the fields 46 description. 47 48 @param inET: lxml element tree to expand 49 @return: lxml element tree with expanded structures 50 ''' 51 import copy 52 outET = copy.deepcopy(inET) 53 54 root = outET.getroot() 55 includeStructs = root.xpath('message/include-struct') 56 for inc in includeStructs: 57 58 if verbose: print 'inc:',inc.attrib['name'], 'parent:',inc.getparent().tag 59 parent = inc.getparent() 60 nodePosition = getPos(parent,inc) 61 #if verbose: print 'pos:',nodePosition 62 63 structName = inc.attrib['struct'] 64 baseName = inc.attrib['name']+'_' 65 #if verbose: print 'baseName:',baseName, 'structName=',structName 66 67 structDef = root.xpath("struct[@name='"+structName+"']") 68 69 # Put in a comment where the include-struct was. 70 inc.getparent().replace(inc,etree.Comment('Struct include of '+inc.attrib['name']+' was here')) 71 72 replacement=copy.deepcopy(structDef[0]) 73 74 75 # FIX: what happens when the include is at the beginning or end of the list? 76 77 for subfield in replacement.xpath('field'): 78 subfield.attrib['name']=baseName+subfield.attrib['name'] 79 desc = subfield.xpath('description') 80 if len(desc)==1: 81 desc[0].text= inc.xpath('description')[0].text +'\n\n'+ desc[0].text 82 else: 83 print 'WARNING: no description for subfield!!!! Must have exactly one description field' 84 # Now that the node is ready, jam it in there after the replaced comment 85 86 print "FIX: make sure these end up in the right place!!!!" 87 88 newPos = nodePosition+getPos(replacement,subfield) #+1 89 nodePosition+=1 90 parent.insert(newPos,subfield) 91 #if verbose: print 'New parent:',etree.tostring(parent) 92 93 return outET
94
95 -def nukeStructs(inET,verbose=False):
96 ''' 97 Replace each include-struct with the structure. This code is not 98 pretty, but it seems to work. The include-struct name is 99 prepended to each field name within the struct. The 100 include-struct description is also added to before the fields 101 description. 102 103 @param inET: lxml element tree to expand 104 @return: lxml element tree with expanded structures 105 ''' 106 import copy 107 outET = copy.deepcopy(inET) 108 109 root = outET.getroot() 110 structs = root.xpath('struct') 111 for struct in structs: 112 if verbose: print 'nuking struct:',struct.attrib['name'] 113 struct.getparent().replace(struct,etree.Comment('Struct '+struct.attrib['name']+' was here')) 114 115 return outET
116 117 if __name__ == '__main__': 118 from optparse import OptionParser 119 myparser = OptionParser(usage="%prog [options]", 120 version="%prog "+__version__) 121 myparser.add_option('-i','--input-file',dest='inFilename',default=None, 122 help='AIS to read from') 123 myparser.add_option('-o','--output-file',dest='outFilename',default='out-ais.xml', 124 help='New AIS file that has structures expanded') 125 myparser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 126 help='Verbose mode') 127 128 myparser.add_option('-k','--keep-structs',dest='keepStructs',default=False,action='store_true', 129 help='Keep the structure definitions at the beginning of the file') 130 (options,args) = myparser.parse_args() 131 132 newET = expandAis(etree.parse(options.inFilename),options.verbose) 133 if not options.keepStructs: 134 newET = nukeStructs(newET,options.verbose) 135 newET.write(options.outFilename) 136 137 #if options.verbose: print etree.tostring(newET) 138