【问题标题】:Iteratively write XML nodes in python在python中迭代地编写XML节点
【发布时间】:2011-03-21 13:06:56
【问题描述】:

读取 XML 的方法有很多种,包括一次性 (DOM) 和一次一位 (SAX)。我使用 SAX 或 lxml 迭代读取大型 XML 文件(例如 6.5GB 压缩的维基百科转储)。

但是,在对该 XML 文件进行一些迭代处理(在 python 中使用 ElementTree)之后,我想将(新的)XML 数据写入另一个文件。

是否有任何库可以迭代地写出 XML 数据?我可以创建 XML 树,然后将其写出来,但如果没有大量 ram,这是不可能的。反正有没有迭代地将 XML 树写入文件?一次一点?

我知道我可以自己使用print "<%s>" % tag_name 等生成 XML,但这似乎有点……hacky

【问题讨论】:

标签: python xml memory


【解决方案1】:

Fredrik Lundh 的elementtree.SimpleXMLWriter 可以让您逐步写出XML。这是嵌入在模块中的演示代码:

from elementtree.SimpleXMLWriter import XMLWriter
import sys

w = XMLWriter(sys.stdout)

html = w.start("html")

w.start("head")
w.element("title", "my document")
w.element("meta", name="generator", value="my application 1.0")
w.end()

w.start("body")
w.element("h1", "this is a heading")
w.element("p", "this is a paragraph")

w.start("p")
w.data("this is ")
w.element("b", "bold")
w.data(" and ")
w.element("i", "italic")
w.data(".")
w.end("p")

w.close(html)

【讨论】:

    【解决方案2】:

    使用 lxml,您可以使用 etree.Element 创建新节点,并使用 etree.tostring 写出 XML 表示。例如,参见Liza Daly's article 中的Listing 6. Serialize an element's children“使用 lxml 在 Python 中进行高性能 XML 解析”。

    【讨论】:

    • 为了使用etree.tostring,我是否需要将整个树保存在内存中?如果是这样,这是一个非跑步者。
    • @Rory:fast_iter 函数遍历节点而不生成整个 DOM。然后,您可以一次修改部分或全部这些节点,并使用etree.tostring 将它们写出来。
    【解决方案3】:

    如果您正在阅读 XML dialect1,并且必须编写 XML dialect2,那么使用 xslt 写下转换过程不是一个好主意吗?这样你甚至可能不需要任何源代码。

    【讨论】:

    • 我不介意编程或不编程。最重要的是内存消耗。我没有空间将所有源文档存储在内存中。 XSLT 不是内存密集型的吗? (也就是说,这不是发明 STX 的原因吗?)
    • @Rory:xslt 允许您以声明的方式指定转换。然后您可以使用手头的工具应用转换。我必须承认我还不必担心可扩展性。我建议您看看可用的 XSLT 处理器。第一眼告诉我,例如撒克逊人有一个“懒惰的建设”模式 (saxonica.com/documentation/javadoc/net/sf/saxon/lib/…)
    【解决方案4】:

    如果你没有找到任何其他东西,我更喜欢从 ElementTree 继承并创建一个“iteractiveElementTree”,并为其添加一个“文件”属性。我将节点子类化为具有“start_tag_comitted”属性和“commit”方法。在被调用时,这个“提交”方法将调用子树的渲染方法——从最远的父级开始,其中 e"start_tag_comitted" 为假。有了手中的字符串,我将手动剥离当前节点父节点的结束标签。还需要处理先前打开但未关闭的父兄弟姐妹。

    然后,我会从内存模型中删除“已提交”节点。 您还需要为每个节点注释节点父节点,因为 ElementTree 不会这样做。

    (如果没有更好的答案并且你卡在那里,请写信给我,我可以实现这个)

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 2011-04-25
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-22
      相关资源
      最近更新 更多