Martin已經看過了我的代碼,并且提出了意見,我們最擔心的問題——性能問題還是凸顯出來了,并不奇怪,erwin導出的文件確實是非常龐大的。
          我在python郵件列表里面查找了一下,找到了幾個常見的解決方案:
          1. 使用4suite提供的cDomleete
          2. 通過pywin32通過com調用ms的MSXML解析器
          3. PIRXX一個和xerces綁定的dom
          4suite提供的cDomleete看起來是個比較不錯的選擇,我對解析的腳本作了一點小的改動:
            1 import logging,logging.handlers
            2 logging.basicConfig(level=logging.DEBUG,\
            3         format='%(asctime)s %(levelname)s %(message)s',\
            4         filename='trans2.log',\
            5         filemode='w')
            6 logger = logging.getLogger('trans2')
            7 
            8 class entity:
            9 
           10     def _parse_entity_properties(self, root):
           11         entity_attrs_map = _get_attributes_as_dict(root)
           12         self.id = entity_attrs_map['id']
           13         self.name = entity_attrs_map['Name']
           14         
           15         entity_properties_map = _get_child_nodes_as_dict(root.firstChild)
           16         if 'Physical_Name' in entity_properties_map:
           17             logger.debug('found Physical_Name in entity(%s)' % self.id)
           18             self.physical_name = entity_properties_map['Physical_Name']
           19         else:
           20             self.physical_name = ''
           21         logger.info('entity id = %s, name=%s, physical_name=%s'\
           22                 % (self.id, self.name,self.physical_name))
           23 
           24     def _parse_entity_attributes(self, root):
           25         self.attrs = []
           26         #attr_list = root.getElementsByTagName('Attribute')
           27         attr_list = root.xpath('//Attribute')
           28         for a in attr_list:
           29             attr_map = {}
           30             id = _get_attributes_as_dict(a)['id']
           31             name = _get_attributes_as_dict(a)['Name']
           32 
           33             child_map = _get_child_nodes_as_dict(a.firstChild)
           34             pysical_name = ''
           35             parent_attr_id = ''
           36             parent_relation_id = ''
           37             master_attr_id = ''
           38             nullable = 1
           39             try:
           40                 #for process some special cases
           41                 if 'Physical_Name' in child_map:
           42                     logger.debug('found Physical_Name element in Attribute(%s)' % id)
           43                     pysical_name = child_map['Physical_Name'].firstChild.data
           44                 if 'Parent_Attribute' in child_map:
           45                     logger.debug('found Parent_Attribute element in Attribute(%s)' % id)
           46                     parent_attr_id = child_map['Parent_Attribute'].firstChild.data 
           47                 if 'Parent_Relationship' in child_map:
           48                     logger.debug('found Parent_Relationship element in Attribute(%s)' % id)
           49                     parent_relation_id = child_map['Parent_Relationship'].firstChild.data 
           50                 if 'Master_Attribute' in child_map:
           51                     logger.debug('found Master_Attribute element in Attribute(%s)' % id)
           52                     master_attr_id = child_map['Master_Attribute'].firstChild.data 
           53                 if 'Null_Option' in child_map:
           54                     logger.debug('found Null_Option element in Attribute(%s)' % id)
           55                     nullable = child_map['Null_Option'].firstChild.data
           56                 data_type = child_map['Datatype'].firstChild.data
           57 
           58                 attr_map = {'attr_id':id,'name':name,'pysical_name':pysical_name,\
           59                         'nullable':nullable,'data_type':data_type,'parent_attr_id':parent_attr_id\
           60                         ,'parent_relation_id':parent_relation_id ,'master_attr_id':master_attr_id }
           61             except KeyError,msg:
           62                 print 'warring, maybe missing some attribute\'s infomation:%s of entity %s'\
           63                         % (msg, self.name)
           64                 logger.warn('warring, maybe missing some attribute\'s infomation:%s of entity %s'\
           65                         % (msg, self.name))
           66         self.attrs.append(attr_map)
           67 
           68     def _parse_entity_keys(self, root):
           69         self.pk = {} 
           70         self.fks = []
           71         #key_list = root.getElementsByTagName('Key_Group')
           72         key_list = root.xpath('//Key_Group')
           73         for k in key_list:
           74             key_id = _get_attributes_as_dict(k)['id'
           75             key_name = _get_attributes_as_dict(k)['Name']
           76             # process Key_GroupProps, get the key type infomation 
           77             key_type = _get_child_nodes_as_dict(k.firstChild)['Key_Group_Type'].firstChild.data 
           78             # process Key_Group_MemberProps, get the key column property
           79             #try:
           80             if 'Key_Group_Member_Column' in _get_child_nodes_as_dict(\
           81                     k.lastChild.firstChild.firstChild):
           82                 key_attr_id =  _get_child_nodes_as_dict(k.lastChild.firstChild.firstChild)\
           83                         ['Key_Group_Member_Column'].firstChild.data
           84             else:
           85                 logger.error('error, can\'t find the key defination %for %s'\
           86                                % ('Key_Group_Member_Column', self.name))
           87                 key_attr_id = ''
           88 
           89             key_conf = {'key_id':key_id,'key_name':key_name,\
           90                 'key_type':key_type,'key_attr_id':key_attr_id}
           91             if key_conf['key_type'== 'PK':
           92                 self.pk = key_conf
           93             else:
           94                 self.fks.append(key_conf)
           95                 logger.debug('key_props for Key_Group(%s):%s:%s:%s'\
           96                             % (key_id,key_name,key_type,key_attr_id))
           97             #except KeyError, msg:
           98             #    print 'error, can\'t find the key defination %s for %s'\
           99             #           % (msg, self.name)
          100             #    logger.error('error, can\'t find the key defination %s for %s'\
          101             #           % (msg, self.name))
          102 
          103 
          104     def _reset(self):
          105         self.id = ''
          106         self.name = ''
          107         self.attrs = []
          108         self.pk = {}
          109         self.fks = []
          110 
          111     def __init__(self,entity_element):
          112         self._reset()
          113         self._parse_entity_properties(entity_element)
          114         self._parse_entity_attributes(entity_element)
          115         self._parse_entity_keys(entity_element)
          116 
          117     def __eq__(a,b):
          118         return a.id == b.id
          119 
          120     def __repr__(self):
          121         #print self.__dict__
          122         return 'entity with {id:%(id)s,name:%(name)s,pk:%(pk)s' \
          123                 % self.__dict__
          124 
          125 class relationship:
          126     def __init__(self,relation_element):
          127         self._reset()
          128         self._parse_relationship(relation_element)
          129 
          130     def _reset(self):
          131         self.id = ''
          132         self.parent_id = ''
          133         self.child_id = ''
          134         self.name = ''
          135         
          136     def _parse_relationship(self, relations_element):
          137         attr_map = _get_attributes_as_dict(relations_element)
          138         self.id = attr_map['id']
          139         self.name = attr_map['Name']
          140         
          141         rel_props = _get_child_nodes_as_dict(relations_element.childNodes[0]) 
          142         self.parent_id = rel_props['Relationship_Parent_Entity'].firstChild.data
          143         self.child_id = rel_props['Relationship_Child_Entity'].firstChild.data
          144         logger.debug('parsed relation:%s:' % self)
          145 
          146     def __repr__(self):
          147         return 'relationship with {id:%(id)s,name:%(name)s,parent_id:%(parent_id)s,child_id:%(child_id)s}' \
          148                 % self.__dict__
          149 
          150     def __eq__(a, b):
          151         return a.id == b.id
          152 
          153 def _get_attributes_as_dict(element):
          154     attrs = {}
          155     if element.attributes:
          156         for attr in element.attributes.values():
          157             attrs[attr.name.strip()] = attr.value
          158     return attrs
          159 
          160 def _get_child_nodes_as_dict(element):
          161     child_nodes_map = {}
          162     if element.childNodes:
          163         for e in element.childNodes:
          164             if not e.nodeType == e.TEXT_NODE:
          165                 child_nodes_map[e.tagName.strip()] = e
          166             else:
          167                 child_nodes_map[e.parentNode.tagName.strip()] = e.data
          168     return child_nodes_map
          169 
          170 def parseXmlFile(file_name):
          171     from xml.dom.ext.reader import Sax2 as parser
          172     from Ft.Xml.InputSource import InputSourceFactory
          173     from Ft.Xml.cDomlette import Parse
          174     f = None
          175     docContent = ''
          176     try:
          177         f = file(file_name)
          178         docContent = '\n'.join(f.readlines())
          179     finally:
          180         f.close()
          181     #doc = parser.FromXmlFile(file_name)
          182     doc = Parse(InputSourceFactory().fromString(docContent))
          183     return doc
          184 
          185 def _startParse(root):
          186     #entities = root.getElementsByTagName('Entity')
          187     #relations = root.getElementsByTagName('Relationship')
          188     entities = root.xpath(u'//Entity')
          189     relations = root.xpath(u'//Relationship')
          190     parsed_entities = [entity(item) for item in entities]
          191     parsed_relations = [relationship(item) for item in relations]
          192     return parsed_entities,parsed_relations
          193 
          194 if __name__ == '__main__':
          195     import sys,time
          196     start = time.time()
          197     print 'start@%s' % start
          198     root = parseXmlFile(sys.argv[1])
          199     entities,relations = _startParse(root.documentElement)
          200     end = time.time()
          201     print 'stop@%s' % end
          202     logger.info('cost %ss' % (end - start)) 
          203     print 'cost %s' % (end - start) 
          204 
          除了對解析器的初始化代碼改動了之外,dom的getElementsByTagName被一個Xpath表達式取代了,這個變化其實也不是太大,另外,我把一些依靠異常處理的代碼路徑截掉,主要是考慮構造異常對象是一個比較耗時的操作。 經過測試,最終的結果是大約加速了4倍,不知道這個結果能不能令人滿意,但是從主觀感覺來看,解析的時間確實大大縮短了。我使用的xpath表達式可能也影響了效率,這種問題還是交給Martin來幫我看看吧。

          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           

          posts - 16, comments - 3, trackbacks - 0, articles - 0

          Copyright © Under the sunshine

          主站蜘蛛池模板: 辽宁省| 徐汇区| 井陉县| 永仁县| 建始县| 松原市| 绥滨县| 长兴县| 姜堰市| 扎兰屯市| 锡林郭勒盟| 凉山| 长沙县| 嘉鱼县| 凭祥市| 永德县| 安西县| 梅河口市| 巴东县| 临武县| 婺源县| 凌云县| 兴业县| 沂水县| 文水县| 芜湖市| 鸡西市| 太保市| 子长县| 望谟县| 盐城市| 循化| 三穗县| 平湖市| 千阳县| 若尔盖县| 宁波市| 施秉县| 紫云| 泉州市| 会泽县|