2 # -*- coding: iso-8859-1 -*-
4 from xml.sax import saxutils
21 # Caracteres a eliminar
24 class ObjFinder(saxutils.DefaultHandler):
30 def startElement(self, name, attrs):
31 #print " #### Start <%s %s>" % (name, dict(attrs))
32 if name == 'dia:object': # Comienzo de una clase
33 if attrs.get('type', None) == 'UML - Class':
36 elif name == 'dia:attribute':
37 name = attrs.get('name', None)
38 if self.estado == E_CLASS: # Datos de la clase
39 if name == 'name': # Nombre de la clase
40 self.curr['name'] = ''
41 self.estado = E_CLASS_NAME
42 elif name == 'comment': # Es la descripción de la clase
43 self.curr['comment'] = ''
44 self.estado = E_CLASS_COMMENT
45 elif name == 'attributes': # Paso empezó a encontrar atributos
46 self.curr['attrs'] = []
48 elif name == 'operations': # Paso empezó a encontrar operaciones
51 elif self.estado == E_ATTR: # Datos del atributo
52 if name == 'name': # Nombre del atributo
53 self.curr_attr['name'] = ''
54 self.estado = E_ATTR_NAME
55 elif name == 'type': # Es el tipo del atributo
56 self.curr_attr['type'] = ''
57 self.estado = E_ATTR_TYPE
58 elif name == 'comment': # Es la descripción del atributo
59 self.curr_attr['comment'] = ''
60 self.estado = E_ATTR_COMMENT
61 elif self.estado == E_OP: # Datos del atributo
62 if name == 'name': # Nombre del atributo
63 self.curr_op['name'] = ''
64 self.estado = E_OP_NAME
65 elif name == 'type': # Es el tipo del atributo
66 self.curr_op['type'] = ''
67 self.estado = E_OP_TYPE
68 elif name == 'comment': # Es la descripción del atributo
69 self.curr_op['comment'] = ''
70 self.estado = E_OP_COMMENT
71 elif name == 'dia:composite': # Comienzo de attributos de clase
72 if self.estado == E_ATTRS: # Si estoy en una clase
74 self.estado = E_ATTR # Paso a buscar sus operaciones
75 elif self.estado == E_OPS: # Si estoy en una clase
77 self.estado = E_OP # Paso a buscar sus atributos
78 def characters(self, data):
79 if self.estado == E_CLASS_NAME:
80 self.curr['name'] += data.strip(STRIPCHARS)
81 elif self.estado == E_CLASS_COMMENT:
82 self.curr['comment'] += data.strip(STRIPCHARS)
83 elif self.estado == E_ATTR_NAME:
84 self.curr_attr['name'] += data.strip(STRIPCHARS)
85 elif self.estado == E_ATTR_TYPE:
86 self.curr_attr['type'] += data.strip(STRIPCHARS)
87 elif self.estado == E_ATTR_COMMENT:
88 self.curr_attr['comment'] += data.strip(STRIPCHARS)
89 elif self.estado == E_OP_NAME:
90 self.curr_op['name'] += data.strip(STRIPCHARS)
91 elif self.estado == E_OP_TYPE:
92 self.curr_op['type'] += data.strip(STRIPCHARS)
93 elif self.estado == E_OP_COMMENT:
94 self.curr_op['comment'] += data.strip(STRIPCHARS)
95 def endElement(self, name):
96 #print " #### Endt </%s>" % name
97 if name == 'dia:object':
98 if self.estado == E_CLASS:
99 self.clases.append(self.curr)
102 elif name == 'dia:attribute':
103 if self.estado == E_CLASS_NAME:
104 self.estado = E_CLASS
105 elif self.estado == E_CLASS_COMMENT:
106 self.estado = E_CLASS
107 elif self.estado == E_ATTR_NAME:
109 elif self.estado == E_ATTR_TYPE:
111 elif self.estado == E_ATTR_COMMENT:
113 elif self.estado == E_ATTRS:
114 self.estado = E_CLASS
115 elif self.estado == E_OP_NAME:
117 elif self.estado == E_OP_TYPE:
119 elif self.estado == E_OP_COMMENT:
121 elif self.estado == E_OPS:
122 self.estado = E_CLASS
123 elif name == 'dia:composite':
124 if self.estado == E_ATTR:
125 self.curr['attrs'].append(self.curr_attr)
126 self.curr_attr = None
127 self.estado = E_ATTRS
128 elif self.estado == E_OP:
129 self.curr['ops'].append(self.curr_op)
134 if __name__ == '__main__':
136 from xml.sax import make_parser
137 from xml.sax.handler import feature_namespaces
139 # Verifica parámetros
140 if len(sys.argv) < 2:
141 print >>sys.stderr, 'Uso:', sys.argv[0], 'archivo.dia [-n]'
142 print >>sys.stderr, '-n si no se quieren incluir los métodos'
146 parser = make_parser()
148 # Tell the parser we are not interested in XML namespaces
149 parser.setFeature(feature_namespaces, 0)
154 # Tell the parser to use our handler
155 parser.setContentHandler(dh)
158 parser.parse(sys.argv[1])
160 # Veo si hay que poner métodos
162 if len(sys.argv) > 2 and sys.argv[2] == '-n':
165 print '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">'
166 print '<html lang="es"><head><title>Especificación</title></head><body>'
167 # Recorro clases obtenidas
169 print '<table width="100%%" border="1" summary="Especificación de clase %s">' \
170 % c['name'].encode('iso-8859-1', 'replace')
171 print '<tr><th colspan="3">%s</th></tr>' % c['name'].encode('iso-8859-1', 'replace')
172 print '<tr><td colspan="3">%s</td></tr>' % c['comment'].encode('iso-8859-1', 'replace')
173 print '<tr><th>Atributo</th><th>Tipo</th><th>Descripción</th></tr>'
175 print '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' \
176 % (a['name'].encode('iso-8859-1', 'replace'),
177 a['type'].encode('iso-8859-1', 'replace'),
178 a['comment'].encode('iso-8859-1', 'replace'))
180 print '<tr><th>Método</th><th>Retorno</th><th>Descripción</th></tr>'
182 print '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' \
183 % (o['name'].encode('iso-8859-1', 'replace'),
184 o['type'].encode('iso-8859-1', 'replace'),
185 o['comment'].encode('iso-8859-1', 'replace'))
187 print '</body></html>'
190 # vim: set et sw=4 sts=4 :