2013-04-02 6 views
0

Я написал класс, унаследованный от класса xml.etree.ElementTree.Element, чтобы расширить этот класс с помощью методов, чтобы показать полное имя тега элемента etree и простой способ заменить полное содержимое элемента значением XML из строки ..Python, etree: как скопировать экземпляр в новый экземпляр унаследованного класса?

В init метод нового класса я просто хочу иметь копию элемента etree, переданного в качестве параметра при инстанцировании.

Первая попытка была:

def __init__(self, elem): 
    self = elem 

Но тогда "подтеги" список пройденному "Element" заблудился.

Решение ниже работает, но есть ли более «умный» способ скопировать полный «elem» в новый объект?

import xml.etree.ElementTree as ET 

# 
# this class allows to replace the content including all subelement of an etree element 
# by an XML string content 
# 

class xmltag(ET.Element): 

    # constructor 
    def __init__(self, elem): 

     self.tag = elem.tag 
     self.text = elem.text 
     self.attrib = elem.attrib 
     self.tail = elem.tail 
     for s in next(elem.iter()): 
      self.append(s) 


    # get string of complete start tag name      
    def __get_tag_start(self): 
     tag="<"+self.tag 
     for k in self.attrib.keys(): 
      tag=tag+" "+k+"=\"" + self.attrib[k] + "\"" 

     return tag+">" 

    # get string of end tag name 
    def __get_tag_end(self): 
     return "</" + self.tag + ">" + (self.tail or "") 

    # get string of whole content between start and end tag 
    def get_tag_content(self): 

     content=self.text or "" 
     for s in next(self.iter()): 
      xs=xmltag(s)    
      content=content+xs.__get_tag_start() 
      content=content+(xs.text or "") 
      content=content+xs.__get_tag_end() 

     return content 

    # change tag name 
    def set_tag_name(self,tagname): 
     self.tag=tagname  

    # change content 
    def set_tag_content(self,content): 
     try: 
      elem=ET.fromstring(self.__get_tag_start()+content+self.__get_tag_end()) 

      self.clear() 
      self.tag = elem.tag 
      self.text = elem.text 
      self.attrib = elem.attrib 
      self.tail = elem.tail 
      for s in next(elem.iter()): 
       self.append(s) 

      elem.clear() 

     except: 
      pass 

# 
# testdata 
# 

xmldata="""<?xml version="1.0"?> 
<data> 
    <country name="Liechtenstein"> 
     <rank>1</rank> 
     <year>2008</year> 
     <gdppc>141100</gdppc> 
     <neighbor name="Austria" direction="E"/> 
     <neighbor name="Switzerland" direction="W"/> 
    </country> 
    <country name="Singapore"> 
     <rank>4</rank> 
     <year>2011</year> 
     <gdppc>59900</gdppc> 
     <neighbor name="Malaysia" direction="N"/> 
    </country> 
    <country name="Panama"> 
     <rank>68</rank> 
     <year>2011</year> 
     <gdppc>13600</gdppc> 
     <neighbor name="Costa Rica" direction="W"/> 
     <neighbor name="Colombia" direction="E"/> 
    </country> 
</data>""" 

# 
# MAIN 
# 

if __name__ == "__main__": 

    root = ET.fromstring(xmldata) 
    element=root.find("country") 

    if ET.iselement(element): 

     x=xmltag(element) 
     print(x.get_tag_content()) 

     x.set_tag_content("abc") 
     print(ET.tostring(x,encoding="unicode")) 

     x.set_tag_content("EFG") 
     print(ET.tostring(x,encoding="unicode")) 

     x.set_tag_name("test") 
     print(ET.tostring(x,encoding="unicode")) 
+0

Выполнение 'self = something' ничего не меняет. Вы просто привязываете имя 'self' к чему-то еще на протяжении выполнения' __init__', но вне ссылок не изменяется. Поскольку у вас есть рабочее решение, и вы хотите его улучшить, вероятно, вы должны перенести этот вопрос на codereview SE. – Bakuriu

+0

Возможный дубликат [классы в Python для новичков] (http://stackoverflow.com/questions/7993089/classes-in-python-for-a-beginner) –

ответ

0

Это исправляет ошибку в оригинальном __init__() методе:

def __init__(self, elem): 
    self.elem = elem 

Это копирует весь elem в вашем экземпляре и теперь вы можете получить доступ к его свойства, такие как self.elem.tag или self.elem.text.

Смежные вопросы