【问题标题】:Parsing very large xml lazily懒惰地解析非常大的xml
【发布时间】:2012-10-22 11:04:49
【问题描述】:

我有一个巨大的 xml 文件 (40 gbs)。我想从中提取一些字段而不将整个文件加载到内存中。有什么建议吗?

【问题讨论】:

  • 看看scala的XMLEventReader

标签: scala xml-parsing


【解决方案1】:

用户SAXParser,它不会将整个xml加载到内存中。 Here 很好的java例子,很容易在scala中使用。

【讨论】:

    【解决方案2】:

    基于 SAXParser here 的教程的 XMLEventReader 快速示例(由 Rinat Tainov 发布)。

    我确信它可以做得更好,但只是为了展示基本用法:

    import scala.io.Source
    import scala.xml.pull._
    
    object Main extends App {
      val xml = new XMLEventReader(Source.fromFile("test.xml"))
    
      def printText(text: String, currNode: List[String]) {
        currNode match {
          case List("firstname", "staff", "company") => println("First Name: " + text)
          case List("lastname", "staff", "company") => println("Last Name: " + text)
          case List("nickname", "staff", "company") => println("Nick Name: " + text)
          case List("salary", "staff", "company") => println("Salary: " + text)
          case _ => ()
        }
      }
    
      def parse(xml: XMLEventReader) {
        def loop(currNode: List[String]) {
          if (xml.hasNext) {
            xml.next match {
              case EvElemStart(_, label, _, _) =>
                println("Start element: " + label)
                loop(label :: currNode)
              case EvElemEnd(_, label) =>
                println("End element: " + label)
                loop(currNode.tail)
              case EvText(text) =>
                printText(text, currNode)
                loop(currNode)
              case _ => loop(currNode)
            }
          }
        }
        loop(List.empty)
      }
    
      parse(xml)
    }
    

    【讨论】:

    • 如果 XMLEventReader 从带有连接的 url 获取 xml 怎么办?然后在惰性评估完成之前连接到该 url 超时。关于这个问题有什么想法吗?
    • 在传输数据时,URLConnection 不会超时。否则将无法进行长期下载;) ... 如果在设定的时间段内未收到任何数据包,则连接超时。
    • 你能帮我看看“循环”在做什么吗?据我了解它循环标签,但我不确定。寻找任何提到它但找不到的文档。我知道这是一个旧帖子,但有人可以帮忙吗?即使是链接也会有所帮助。同时我也在寻找
    • @Vikash 它更像是遇到某些 XML 元素时生成的事件。查看可用事件类型的文档(在“已知子类”下):scala-lang.org/api/2.12.2/scala-xml/scala/xml/pull/…
    • @Arjan 谢谢。那时我不知道尾递归,因为我刚开始使用 scala。如果我没记错的话,这看起来更像。
    【解决方案3】:

    如果您对替代 xml 库感到满意,那么 Scales Xml 提供了三种主要的拉式解析方法:

    1. Iterator based - 只需使用 hasNext,next 即可获得更多项目
    2. iterate function - 提供一个迭代器,但用于由简单路径标识的树
    3. Iteratee based - 允许组合多条路径

    即将发布的 0.5 版本的重点是通过 aalto-xml 进行异步解析,允许额外的非阻塞控制选项。

    在所有情况下,您都可以控制内存使用以及使用 Scales 处理文档的方式。

    【讨论】:

      猜你喜欢
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 2018-08-20
      • 1970-01-01
      • 2013-02-28
      相关资源
      最近更新 更多