У меня есть фрагмент XML, который содержит иерархию объектов:
doc = """\
<RootObj val1="ValueOne" stat1="Stat1" stat2="Stat2">
<internalarray type="array">
<InternalObject val1="12" val2="12" />
<InternalObject val1="13" val2="13" />
<InternalObject val1="14" val2="14" />
<InternalObject val1="15" val2="15" />
</internalarray>
</RootObj>"""
Я использую XML-представление ElementTree для анализа xml:
from xml.etree import ElementTree as ET
...
xml_doc = ET.XML(doc)
Я рекурсивно перебираю элементы xml_doc, создавая определения классов, используя "namedtuple":
from collections import namedtuple
...
def buildClass(name, node):
symbol_table = {}
args = []
varnames = ""
for subnode in node:
args.append(buildClass(subnode.tag, subnode))
if (subnode.tag not in symbol_table):
symbol_table[subnode.tag] = 1
varnames += subnode.tag + " "
print 'Building class for:', name
for (key, value) in node.items():
args.append(value)
varnames += key + " "
varnames = varnames.strip()
if (not name[0] == name[0].upper()):
#this is an array, do not create a class, just return an array
#pop the last element, "array"
args.pop()
return args
globals()[name] = namedtuple(name, varnames)
obj = globals()[name](*args)
return obj
Что называется так:
rootObj = build_class(xml_doc.tag, xml_doc)
Использование дампа, функции, найденной в другом месте в StackOverflow:
def dump(obj):
'''return a printable representation of an object for debugging'''
newobj=obj
if '__dict__' in dir(obj):
newobj=obj.__dict__
if ' object at ' in str(obj) and not newobj.has_key('__type__'):
newobj['__type__']=str(obj)
for attr in newobj:
newobj[attr]=dump(newobj[attr])
return newobj
Вы можете позвонить:
print dump(rootObj)
И посмотрите (я отформатировал интервал вручную):
RootObj(
internalarray=[
InternalObject(val2='12', val1='12'),
InternalObject(val2='13', val1='13'),
InternalObject(val2='14', val1='14'),
InternalObject(val2='15', val1='15')
],
val1='ValueOne', stat2='Stat2', stat1='Stat1')
Итак, мы знаем, что код на самом деле генерирует класс. Теперь, если вы используете amfast DynamicClassMapper и генератор кода:
import amfast
from amfast import class_def
from amfast.class_def.code_generator import CodeGenerator
...
class_mapper = class_def.ClassDefMapper()
mapped_class = class_def.DynamicClassDef(RootObj, 'RootObj', ())
#OR
#mapped_class = class_def.DynamicClassDef(globals()[xml_doc.tag],xml_doc.tag, ())
#I tried both and received the same output
coder = CodeGenerator()
coder.generateFilesFromMapper(class_mapper, use_accessors=False,
packaged=True, constructor=True, bindable=True, extends='Object')
Вы получаете файл, RootObj.as:
package
{
[Bindable]
[RemoteClass(alias='RootObj')]
public dynamic class RootObj extends Object
{
public function RootObj():void
{
super();
}
}
}
В котором явно отсутствуют все атрибуты и еще много чего. Есть ли способ использовать эту методологию кодирования для вывода файла ActionScript, который на самом деле содержит правильное определение класса?