9

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

4

3 回答 3

22

XMLEventReader 的快速示例基于此处的 SAXParser 教程(由 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)
}
于 2012-11-02T10:46:22.010 回答
2

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

于 2012-11-02T04:38:24.203 回答
2

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

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

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

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

于 2012-11-04T23:01:41.220 回答