1
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
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
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
62
63 structName = inc.attrib['struct']
64 baseName = inc.attrib['name']+'_'
65
66
67 structDef = root.xpath("struct[@name='"+structName+"']")
68
69
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
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
85
86 print "FIX: make sure these end up in the right place!!!!"
87
88 newPos = nodePosition+getPos(replacement,subfield)
89 nodePosition+=1
90 parent.insert(newPos,subfield)
91
92
93 return outET
94
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
138