5

我目前正在解析大于 40 MB 的非常大的 xml 文件。我刚刚开始在 scala 中进行开发,所以我在网上浏览了一些好的库并偶然发现了 Scala Scales,它似乎非常擅长处理大文件。

我已阅读: http ://scala-scales.googlecode.com/svn/sites/scales/scales-xml_2.9.1/0.2/ScalesXmlIntro.html,http : //scala-scales.googlecode.com/svn/sites/尺度/scales-xml_2.9.2/0.4.4/PullParsing.html

然后测试 pullXml 函数,以确保正确导入所有库。

val pull = pullXml(new FileReader("/Users/mycrazyxml/tmp/large.xml"))
while( pull.hasNext ){
   pull.next match {
        case Left( i : XmlItem ) =>
          // Handle XmlItem
          Logger.info("XmlItem: "+i)

        case Left( e : Elem ) => {
          // Handle Element
          Logger.info("Element: "+e)
        }

        case Right(endElem) =>
          // Handle endElement
          Logger.info("Endelement: "+endElem)        
      }
    }

这导致整个文件被打印到控制台!好的!现在是时候创建对象并保存到数据库了,但是我在掌握如何以一种好的方式做到这一点时遇到了麻烦。我真的需要一些很好的例子来说明如何做到这一点。

例如。下面的 XML 有几个 Enterprise 元素,它们可以由一个或多个 LocalUnits 组成。这里的想法是创建一个带有 LocalUnits 数组的 Enterprise 对象。当 endElement 是 Enterprise 的结束标记时,使用 Enterprise 对象及其 LocalUnits 调用 save 方法。

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Info SYSTEM "info.dtd">
<Info>
  <Enterprise>
    <RegNo>12345678</RegNo>
    <Address>
      <StreetInfo>
        <StreetName>Infinite Loop</StreetName>
        <StreetNumber>1</StreetNumber>
      </StreetInfo>
    </Address>
    <EName>
      <Legal>Crazy Company</Legal>
    </EName>
    <SNI>
      <Code>00000</Code>
      <Rank>1</Rank>
    </SNI>
    <LocalUnit>
      <CFARNo>987654321</CFARNo>
      <LUType>1</LUType>
      <LUName>Crazy Company Gym</LUName>
      <LUStatus>1</LUStatus>
      <SNI>
        <Code>46772</Code>
        <Rank>1</Rank>
      </SNI>
      <SNI>
        <Code>68203</Code>
        <Rank>2</Rank>
      </SNI>
      <Address>
        <StreetInfo>
          <StreetName>Infinite Loop</StreetName>
          <StreetNumber>1</StreetNumber>
        </StreetInfo>
      </Address>
    </LocalUnit>
    <LocalUnit>
      <CFARNo>987654322</CFARNo>
      <LUType>1</LUType>
      <LUName>Crazy Company Restaurant</LUName>
      <LUStatus>1</LUStatus>
      <SNI>
        <Code>46772</Code>
        <Rank>1</Rank>
      </SNI>
      <SNI>
        <Code>68203</Code>
        <Rank>2</Rank>
      </SNI>
      <Address>
        <StreetInfo>
          <StreetName>Infinite Loop</StreetName>
          <StreetNumber>1</StreetNumber>
        </StreetInfo>
      </Address>
    </LocalUnit>
  </Enterprise>
<Enterprise>
    <RegNo>12345671220</RegNo>
    <Address>
      <StreetInfo>
        <StreetName>Cupertino Road</StreetName>
        <StreetNumber>2</StreetNumber>
      </StreetInfo>
    </Address>
    <EName>
      <Legal>Fun Company HQ</Legal>
    </EName>
    <SNI>
      <Code>00000</Code>
      <Rank>1</Rank>
    </SNI>
    <LocalUnit>
      <CFARNo>987654321</CFARNo>
      <LUType>1</LUType>
      <LUName>Fun Company</LUName>
      <LUStatus>1</LUStatus>
      <SNI>
        <Code>46772</Code>
        <Rank>1</Rank>
      </SNI>
      <SNI>
        <Code>68203</Code>
        <Rank>2</Rank>
      </SNI>
      <Address>
        <StreetInfo>
          <StreetName>Cupertino road</StreetName>
          <StreetNumber>2</StreetNumber>
        </StreetInfo>
      </Address>
    </LocalUnit>       
  </Enterprise>
</Info>

把它们加起来。对于给定的 xml,我应该如何使用 pullXml 创建我的对象并使用它们调用 save 方法?

4

2 回答 2

2
val xmlFile = resource(this, "/data/enterprise_info.xml")
val xml = pullXml(xmlFile)

val Info = NoNamespaceQName("Info")
val Enterprise = NoNamespaceQName("Enterprise")
val LocalUnit = NoNamespaceQName("LocalUnit")
val LocalUnitName = NoNamespaceQName("LUName")
val EName = NoNamespaceQName("EName")
val Legal = NoNamespaceQName("Legal")

val EnterprisePath = List(Info, Enterprise)

// iterate over each Enterprise
// only an Enterprise at a time is in memory
val itr =  iterate(EnterprisePath, xml)

for { 
  enterprise <- itr
  enterpriseName <- enterprise \* EName \* Legal
} {
  println("enterprise "+text(enterpriseName) +" has units:")
  for {
    localUnits <- enterprise \* LocalUnit 
    localName <- localUnits \* LocalUnitName
  }{
    println("  " + text(localName))
  }
  //do a save
}

目前,懒惰地拉入每个 LocalUnit 更加困难,您必须为每个不是 LocalUnit 的小节分隔 Paths。

Hth

于 2013-04-17T07:46:09.697 回答
-1

也许这可以帮助你?我认为使用 xml 的小片段在 Scala 中效果很好。 http://joncook.github.io/blog/2013/11/03/xml-processing-with-scala/

于 2014-01-14T09:02:31.463 回答