【问题标题】:Faster way to traverse through XML in python?在 python 中遍历 XML 的更快方法?
【发布时间】:2015-05-08 21:15:03
【问题描述】:

我有这个 xml 文件布局,我想提取所有孩子的名字(Amy、Max 和 Derek):

  <data>
    <dataentry>
        <Name>John</Name>
        <Birthday>3/3/93</BirthDay>
        <Children>
            <Child> Amy </Child>
            <Child> Max </Child>
            <Child> Derek </Child>
         </Children>
    </dataentry>

    <dataentry>
          ....
    </dataentry>
  </data>

Python 代码:

root = tree.getroot()
for dataentry in root.findall('dataentry'):
   for children in dataentry.findall('Children'):
      for child in children.findall('Child'):
          print child.text

我有这个嵌套的 for 循环,但有更快或更优雅的方法吗?

【问题讨论】:

  • 正则表达式可能更快
  • @Lashane 它可能会更快,但我不确定这是否是正确的做法 (reference)。
  • @alecxe 正则表达式肯定不是解析 xml 或 html 的正确方法,但对于一些简单且定义明确的文件,它们工作得很好
  • @Lashane,正则表达式也可能(也将)错误。添加 CDATA 部分或 cmets,天真的正则表达式不会知道其中的内容不应该匹配。
  • 另外,如果您要为大量数据执行此操作,或者重复执行此类操作,您可能需要考虑使用 XQuery 数据库,该数据库将为您的 XML 内容编制索引(非常)这种类型的快速搜索。

标签: python xml performance parsing xml-parsing


【解决方案1】:

你可以使用xpath()在一个循环中完成它:

for child in root.xpath("./dataentry/Children/Child"):
    print child.text

考虑到data 是您的根。

【讨论】:

  • 它肯定更优雅,但我不确定更快
  • 使用./data/dataentry/Children/Child 将比//data/dataentry/Children/Child 更有效,因为您无需递归搜索起点。当然,这意味着我们需要 OP 来阐明他们的出发点。
  • @CharlesDuffy 起点绝对是data。否则,由于findall() 不是递归的,OP 代码提供的内容将不起作用。我已经编辑了表达式。谢谢!
【解决方案2】:

您可以使用 SAX 解析器来执行此操作。这个想法是解析器将在遍历时执行操作,而不是将所有内容读入树中并稍后搜索子项。这可以节省内存和时间。但是,无论路径如何,这都会打印 所有 child 节点,因此它可能是也可能不是您想要的。

from xml import sax


class SAXParser(sax.ContentHandler):
    def __init__(self):
        self.current_string = None

    def characters(self, content):
        self.current_string = content

    def endElement(self, name):
        if name == 'Child':
            print self.current_string

sax.parseString(<string_to_parse>, SAXParser())

【讨论】:

  • 你可以很容易地采用它来根据路径进行过滤——跟踪我们是否在错误的轨道上(轨道嵌套深度;除dataentry 之外的任何第一级条目,任何第二级条目—— Children 以外的任何第三级条目,或Child 以外的任何第三级条目,并设置一个标志,指示我们可以忽略/丢弃其下的任何数据)。
  • 也就是说,我实际上很好奇在实践中走这条路线是否 更节省 CPU (毫无疑问,它更节省内存) .当然,构建 DOM 结构需要很多费用/开销,但它的开销/开销仅在 C 库代码中完成,而不是在这里我们在 Python 解释器中进行大量调用。
  • 不要忘记实际性能也会因所讨论的 XML 而异。例如,如果一个节点是Child 的概率很低,那么 DOM 方法会浪费大量时间来构建和遍历。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 2021-11-18
  • 2018-12-12
  • 2014-02-25
  • 1970-01-01
  • 2021-04-21
相关资源
最近更新 更多