2011-12-19 4 views
0

を生成する動的Pythonのクラス定義を使用して動的クラスマッピングとコード生成amfast:Iは、オブジェクト階層を含むXMLスニペットを有するActionScriptクラス

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>""" 

Iは、XMLを解析するためのElementTreeのXML表現を使用します。

from xml.etree import ElementTree as ET 
... 
xml_doc = ET.XML(doc) 

私は "namedtuple" を使用して行くようにクラス定義を構築I xml_doc要素を再帰的にループ、:

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 
私はフォーマットされた(

print dump(rootObj) 

をさらに参照してください。あなたが呼び出すことができます

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 

:ダンプ、StackOverflowの上の他の場所に見つかった機能を使用して

rootObj = build_class(xml_doc.tag, xml_doc) 

:このように呼ばれている

手動で間隔を空けてください):

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とコードジェネレータを使用している場合今、:明らかにすべての属性とその他もろもろが欠落している

package 
{ 
    [Bindable] 
    [RemoteClass(alias='RootObj')] 
    public dynamic class RootObj extends Object 
    { 
    public function RootObj():void 
    { 
     super(); 
    } 
    } 
} 

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を取得します。実際に正しいクラス定義が含まれるActionScriptファイルを出力するために、このコーディング方法を利用する方法はありますか?

答えて

0

これは明らかにこれは誰にも知られていない方法なので、私は回避策を考え出しました。

def buildClass(name, node): 
    global _classes 
    symbol_table = {} 
    args = [] 
    varnames = "" 
    varnameswithtypes = "" 
    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 + " " 
     if (not subnode.tag[0] == subnode.tag[0].upper()): 
     varnameswithtypes += subnode.tag + ":array " 
     else: 
     varnameswithtypes += subnode.tag + ":object " 

    print 'Building class for:', name 
    for (key, value) in node.items(): 
    args.append(value) 
    varnames += key + " " 
    if (key == "variable_name"): 
     varnameswithtypes+= key + ":" + value + " " 
    elif (is_numeric(value)): 
     varnameswithtypes+= key + ":numeric" + " " 
    else: 
     varnameswithtypes+= key + ":text" + " " 
    varnames = varnames.strip() 
    varnameswithtypes = varnameswithtypes.strip() 

    if (_classes.has_key(name)): 
    if (len(_classes[name]) < len(varnameswithtypes)): 
     _classes[name] = varnameswithtypes 
    else: 
    _classes[name] = varnameswithtypes 

    if (not name[0] == name[0].upper()): 
    #this is an array, do not create a class, just return an array 
    return args 
    #print varnames, args 
    globals()[name] = namedtuple(name, varnames) 
    obj = globals()[name](*args) 
    #print dump(obj) 
    return obj 
その後

追加:あなたはこのように呼んで

_classdefs = {} 
def getClassDef(name): 
    global _classdefs, _classes 
    _classdefs[name] = "class " + name + "(object):\n def __init__(self):\n"  
    classvars = _classes[name].split(" ") 
    for x in classvars: 
    vals = x.split(":") 
    if (vals[1] == "array"): 
     c = _classes[vals[0]].split(":")[0] 
     if (not _classdefs.has_key(c)): 
     getClassDef(c) 
     _classdefs[name] += " self." + vals[0] + " = []\n" 
    elif (vals[1] == "text"): 
     _classdefs[name] += " self." + vals[0] + " = \"\"\n" 
    elif (vals[1] == "numeric"): 
     _classdefs[name] += " self." + vals[0] + " = 0\n" 
    elif (vals[1] == "object"): 
     if (not _classdefs.has_key(vals[0])): 
     getClassDef(vals[0]) 
     subclassvars = _classes[vals[0]].split(" ") 
     for z in subclassvars: 
     if (z.split(":")[0] == "variable_name"): 
      _classdefs[name] += " self." + z.split(":")[1] + " = " + vals[0] + "()\n" 

は:

getClassDef("RootObj") 
for x in _classdefs.keys(): 
    print _classdefs[x] 

はXMLを使用して

は私がbuildClass()関数のようにのように修正しました
<RootObj val1="ValueOne" stat1="Stat1" stat2="Stat2"> 
    <internalarray> 
    <InternalObject val1="12" val2="12" /> 
    <InternalObject val1="13" val2="13" /> 
    <InternalObject val1="14" val2="14" /> 
    <InternalObject val1="15" val2="15" /> 
    </internalarray> 
    <InternalObject2 val1="12" val2="13" variable_name="intObj2" /> 
</RootObj> 

コードの出力は以下となります。あなたは、通常のようamfast ActionScriptコード生成で使用するの.pyファイルとインポートに保存することができます

class RootObj(object): 
    def __init__(self): 
    self.internalarray = [] 
    self.intObj2 = InternalObject2() 
    self.val1 = "" 
    self.stat2 = "" 
    self.stat1 = "" 

class InternalObject2(object): 
    def __init__(self): 
    self.val2 = 0 
    self.val1 = 0 

class InternalObject(object): 
    def __init__(self): 
    self.val2 = 0 
    self.val1 = 0 

。私に行ってください。

関連する問題