0

我编写了一个继承自 xml.etree.ElementTree.Element 类的类,以使用显示 etree 元素的完整标签名称的方法扩展该类,以及一种用 XML 值替换元素完整内容的简单方法细绳..

在新类的init方法中,我只想在实例化时将 etree 元素的副本作为参数传递。

第一次尝试是:

def __init__(self, elem):
     self = elem

但是随后传递的“元素”的“子标签”列表丢失了。

下面的解决方案有效,但是否有一种“更智能”的方法可以将完整的“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"))
4

1 回答 1

0

这更正了原始__init__()方法中的错误:

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

这会将整个复制elem到您的实例中,您现在可以访问其属性,例如self.elem.tagor self.elem.text

于 2013-04-02T10:24:26.133 回答