如何使用Python标准库在内存中构建大型XML文档?

2 投票
2 回答
1483 浏览
提问于 2025-04-17 21:21

我正在尝试在内存中创建一个很大的XML文件,然后把它放进ESRI特征类的一个Blob字段里。

我试过用elementtree这个库,但Python最终崩溃了。我可能没有用对方法。以下是我代码的一个例子(不是完全准确的):

with update_cursor on feature class:
    for row in update_cursor:
        root = Element("root") 
        tree = ElementTree(root)
        for id in id_list:
            if row[0] in id:
               equipment = Element("equipment") 
               root.append(equipment)

               attrib1 = Element("attrib1")
               equipment.append(attrib1)
               attrib1.text = "myattrib1"

               attrib2 = Element("attrib2")
               equipment.append(attrib2)
               attrib2.text = "myattrib2"

               ....and about 5 more of these appended to equipment

        xml_data = ET.tostring(root)

        insert xml_data into blob field

这是XML的一个例子:

<root>
  <equipment>
    <attrib1>One</attrib1>
    <attrib2>Two</attrib2>
    <attrib3>Three</attrib3>
    ...
    <attrib10>Ten</attrib10>
  </equipment>
  <equipment>
    <attrib1>One</attrib1>
    <attrib2>Two</attrib2>
    <attrib3>Three</attrib3>
    ...
    <attrib10>Ten</attrib10>
  </equipment>
</root>

现在我意识到这样做可能有点初级,但我不太确定在内存中构建这个XML的最佳方法是什么。

在更新游标的每一行中,可能会有多个“设备”元素被添加到根元素下,而每个“设备”元素都有完全相同的子元素,但属性却不同。

我运行这个程序时,发现大约有200个ID与同一行匹配,所以它必须在内存中创建设备元素和所有设备的子元素200次。

那么,使用Python的标准库,在内存中创建XML的最佳方法是什么呢?

2 个回答

2

你可以使用 ET.SubElement 来创建和添加元素:

equipment = ET.SubElement(root, "equipment")
ET.SubElement(equipment, "attrib1").text = "One"
ET.SubElement(equipment, "attrib2").text = "Two"
ET.SubElement(equipment, "attrib3").text = "Three"
...

这样写起来更简洁,也更清楚。

2

你的数据结构看起来非常简单。没必要使用XML库。直接把你的内容写入一个 cStringIO.StringIO 就可以了。

with update_cursor on feature class:
    for row in update_cursor:
        buffer = cStringIO.StringIO()
        buffer.write("<root>\n")
        for id in id_list:
            if row[0] in id:
               buffer.write("    <equipment>\n")
               buffer.write("        <attrib1>One</attrib1>\n")
               buffer.write("        <attrib2>Two</attrib2>\n")
               buffer.write("        <attrib3>Three</attrib3>\n")

               ....and about 5 more of these appended to equipment

               buffer.write("    </equipment>\n")

        buffer.write("</root>\n")

        xml_data = buffer.getvalue()

        insert xml_data into blob field

撰写回答