2017-07-03 45 views
0

筆者確定如何處理以下問題。 比方說,我有這樣一個日誌文件:解析日誌文件並將其轉換爲Scala中的大小寫類

asdasdçkpoiwqe 
askdjadlskjqw 
<stuff> 
    <a>some val</a> 
    <b>some val</b> 
</stuff> 
kasdjllasdj 
clkj 
skdjalkd 
<moreStuff> 
    <c>some val</c> 
    <d>some val</d> 
</moreStuff> 
iuoudnas 
salkdj 
sdmlaks 
<moreStuff> 
    <c>more val</c> 
    <d>some val</d> 
</moreStuff> 
... 

這是我有一些廢話文字,並在中間,一些XML結構以及形成的。 我要分析此文件,並轉換這個XML來區分等級,所以我定義:

case class Stuff(a: String, b: String) 

case class MoreStuff(c: String, d: String) 

和驗證碼:

val filename = "logFile.log" 
for (line <- Source.fromFile(filename).getLines) { 
    line match { 
       case "<stuff>" => parseStuff(line) 
       case "<moreStuff>" => parseMoreStuff(line) 
       case _ => println("Not Defined"+ line) 
      } 
} 

def parseStuff(line: String) = { 
    //Create a List[Stuff] 
} 

def parseMoreStuff(line: String) = { 
    //Create a List[Stuff] 
} 

但顯然,這並不工作,因爲當週期匹配,唯一通過該方法的線路是<stuff><moreStuff>

比我想我可以通過迭代器的方法和內部使next。事情是這樣的:

def parseMoreStuff(line: String, it: Iterator) = { 
    var l = line 
    while(!line.equals("</moreStuff>")){ 
    l += line 
    it.next() 
} 

,現在我有一個String l僅XML內容,我可以當作XML。我運行這個代碼,我得到了一個java.util.NoSuchElementException: next on empty iterator,但無論如何,我認爲這種方法是一個大混亂(即使我可以解決這個例外)。我不喜歡它,所以我的問題是如果有更清晰的方式來解析具有這種特性的日誌文件。

在此先感謝

回答

1

一種方法是先無視垃圾文本:

val xmlAsString = 
    Source.fromFile(filename) 
     .getLines 
     .map(_.trim) 
     .filter(_.startsWith("<")) 
     .mkString 

// <stuff><a>some val</a><b>some val</b></stuff><moreStuff><c>some val</c><d>some val</d></moreStuff><moreStuff><c>more val</c><d>some val</d></moreStuff> 

注意,在上面的代碼中,我轉換IteratorString,所以這可能是,如果一個問題文件中的XML內容太大而不適合內存。接下來,使用Scala的標準XML庫(從Scala 2.11開始,它已被移動到它自己的library),將XML片段聚合成一個XML文檔(爲了使這個複合文檔格式良好,添加一個根元素):

import scala.xml._ 

val xmlDoc = XML.loadString("<stuffRoot>" + xmlAsString + "</stuffRoot>") 

然後,獲得的MoreStuff S的Stuff S和Seq一個Seq

def parseStuff(node: Node): Stuff = { 
    Stuff((node \ "a").toString, (node \ "b").toString) 
} 

def parseMoreStuff(node: Node): MoreStuff = { 
    MoreStuff((node \ "c").toString, (node \ "d").toString) 
} 

val stuffs = (xmlDoc \ "stuff").map(parseStuff) // Seq[Stuff] 
val moreStuffs = (xmlDoc \ "moreStuff").map(parseMoreStuff) // Seq[MoreStuff] 
+0

是的,它的作品,但我的例子是簡化。我可以有一個以'junkxxx value data sdasa'開頭的行,在這種情況下'startsWith(「<」)'中斷。 – MLeiria