2016-04-06 21 views
1

EingangParse XML in Scala

XML-Eingabe in Daten

val data = <Doc><Title>Doc</Title><Type><Type level="0">A</Type><Type level="1">B</Type></Type><Type><Type level="0">C</Type><Type level="1">D</Type><Type level="2">E</Type></Type></Doc> 

Wunsch Ausgang

Title : Doc 
Type_1 : A | B 
Type_2 : C | D | E 

Was ich versucht habe

Für Titel -. (Data // "Title") Text

Die Frage ist mit "Type" Tags im XML

zur Gruppe

Im Folgenden zusammen jede Art Tag benötigen, ist Der Screenshot für alle versuchten Befehle, um Typ zu extrahieren und zu gruppieren, wie oben das gewünschte Ergebnis. Extracting type tags

Brauchen Sie eine Anleitung/Logik, wie wir Typ-Tags nach dem gewünschten Ergebnis gruppieren können.

Antwort

1

Erste Daten:

scala> val data = <Doc><Title>Doc</Title><Type><Type level="0">A</Type><Type level="1">B</Type></Type><Type><Type level="0">C</Type><Type level="1">D</Type><Type level="2">E</Type></Type></Doc> 
data: scala.xml.Elem = <Doc><Title>Doc</Title><Type><Type level="0">A</Type><Type level="1">B</Type></Type><Type><Type level="0">C</Type><Type level="1">D</Type><Type level="2">E</Type></Type></Doc> 

, die in XML wie folgt aussieht:

<Doc> 
    <Title>Doc</Title> 
    <Type> 
     <Type level="0">A</Type> 
     <Type level="1">B</Type> 
    </Type> 
    <Type> 
     <Type level="0">C</Type> 
     <Type level="1">D</Type> 
     <Type level="2">E</Type> 
    </Type> 
</Doc> 

Alle Knoten von Tag Type mit projizierten level Attributen und entsprechendem Wert:

scala> val types = (data \ "Type" \ "Type") map (x => (x \ "@level").text -> x.text) 
types: scala.collection.immutable.Seq[(String, String)] = 
List((0,A), (1,B), (0,C), (1,D), (2,E)) 

groupped durch level:

types.groupBy(_._1).map { case (level, elems) => level -> elems.map(_._2) } 
res3: scala.collection.immutable.Map[String,scala.collection.immutable.Seq[String]] = 
Map(2 -> List(E), 1 -> List(B, D), 0 -> List(A, C)) 

Wenn Sie die Gruppierung wollen wie gewünscht:

Type_1 : A | B 
Type_2 : C | D | E 

dann:

scala> (data \ "Type").zipWithIndex.map {case (s, idx) => idx -> (s \ "Type").map(_.text) } 
res4: scala.collection.immutable.Seq[(Int, scala.collection.immutable.Seq[String])] = 
List((0,List(A, B)), (1,List(C, D, E))) 

Aber es fühlt sich falsch zu mir, weil in XML die Reihenfolge der Elemente/Knoten sollte in der Regel nicht Angelegenheit.

+1

Vielen Dank !! Ich werde mehr auf dem gleichen erkunden ... Genau. aber Sie wissen, was wir das XML nicht ändern können, da diese Quelldatei von anderen Anwendungsteams verwendet wird ... – Debaditya

+1

Ich teile es in 2, um es einfacher zu lesen. Sie können die Variable 'types' durch den obigen Ausdruck ersetzen. –

+0

oh ja ..... hab es :) – Debaditya