HDI:将大型XML字符串写入文件(python xml.dom.minidom)

1 投票
1 回答
1349 浏览
提问于 2025-04-16 21:22

我现在正在使用 xml.dom.minidom 创建大型的 XML 文件,然后通过 toprettyxml 将它们写入文件。不过,我遇到了内存错误,想知道有没有办法将 XML 流式写入文档。

def run(self):
    while True:
        domain = self.queue.get()
        try:
            conn = boto.connect_sdb(awsa, awss)
            sdbdomain = conn.get_domain(domain)
            s3conn = boto.connect_s3(awsa, awss)
            archbucket = s3conn.get_bucket("simpledbbu")
            doc = None
            doc = Document()
            root = doc.createElement("items")
            doc.appendChild(root)
            countermax = 0
            counter = 0
            for item in sdbdomain:
                node = doc.createElement("item")
                node.setAttribute("itemName", item.name)
                for k,v in item.items():
                    if not isinstance(v, basestring):
                        i = 0
                        for val in v:
                            node.setAttribute("{0}::{1}".format(k,i),val)
                            i += 1
                    else:
                        node.setAttribute(k,v)
                root.appendChild(node)
            k = Key(archbucket)
            k.key = "{0}/{1}.xml".format(datetime.date.today().strftime("%Y%m%d"),sdbdomain.name)
            #x = doc.toprettyxml(indent="  ")
            f = open(domain + ".xml", "w")
            f.truncate()
            f.write(doc.toprettyxml(indent="  "))
            f.close()
            #k.content_type.encode('ascii')
            k.set_contents_from_filename(f.name)
            os.remove(os.path.join(os.getcwd(),f.name))
        except:
            print "failed to load domain: {0}".format(domain)
            print formatExceptionInfo()
        finally:
            self.queue.task_done()

1 个回答

1

使用xml.dom.minidom来构建大型的xml文件,然后通过toprettyxml将它们写入文件。

如果你发现内存不够用,那你可能应该停止这样做。

其实你可以通过简单的字符串操作来构建XML。

with open(domain + ".xml", "w") as  f:
    f.write( "<?xml..." )
    f.write( "<items>" )
    for item in sdbdomain:
      buffer= []
      for k,v in item.items():
          if not isinstance(v, basestring):
            for i, val in enumerate(v):
              txt= '{0}::{1}="{2}"'.format(k,i,val)
          else:
            txt= '{0}="{1}"'.format(k,v)
          buffer.append( txt )
       f.write( "  <item {0}/>\n".format( " ".join(buffer) ))
     f.write( "</items>" )
k= ................      
k.set_contents_from_filename(f.name)

像这样做应该可以让你把XML写入一个临时文件,而不需要在内存中创建一个大的DOM对象。

撰写回答