3

I have the following XML file which I want to parse using Scala:

<infoFile xmlns="http://latest/nmc-omc/cmNrm.doc#info" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://latest/nmc-omc/cmNrm.doc#info schema\pmResultSchedule.xsd">
   <fileHeader fileFormatVersion="123456" operator="ABCD">
       <fileSender elementType="MSC UTLI"/>
       <infoCollec beginTime="2011-05-15T00:00:00-05:00"/>
   </fileHeader>

<infoCollecData>
    <infoMes infoMesID="551727">
        <mesPeriod duration="TT1234" endTime="2011-05-15T00:30:00-05:00"/>
        <mesrePeriod duration="TT1235"/>
        <mesTypes>5517271 5517272 5517273 5517274 </measTypes>
        <mesValue mesObj="RPC12/LMI_ANY:Label=BCR-1232_1111, ANY=1111">
           <mesResults>149 149 3 3 </mesResults>
        </mesValue>
    </infoMes>

    <infoMes infoMesID="551728">
        <mesTypes>6132413 6132414 6132415</mesTypes>
        <mesValue measObjLdn="RPC12/LMI_ANY:Label=BCR-1232_64446, CllID=64446">
            <mesResults>0 0 6</mesResults>
        </mesValue>
        <mesValue measObjLdn="RPC13/LMI_ANY:Label=BCR-1232_64447, CllID=64447">
            <mesResults>0 1 6</mesResults>
        </mesValue>
    </infoMes>

    <infoMes infoMesID="551729">
        <mesTypes>6132416 6132417 6132418 6132419</mesTypes>
        <mesValue measObjLdn="RPC12/LMI_ANY:Label=BCR-1232_64448, CllID=64448">
            <mesResults>1 4 6 8</mesResults>
        </mesValue>
        <mesValue measObjLdn="RPC13/LMI_ANY:Label=BCR-1232_64449, CllID=64449">
            <mesResults>1 2 4 5 </mesResults>
        </mesValue>
        <mesValue measObjLdn="RPC13/LMI_ANY:Label=BCR-1232_64450, CllID=64450">
            <mesResults>1 7 8 5 </mesResults>
        </mesValue>
    </infoMes>
</infoCollecData>

I want the file to be parsed as follows:

From the fileHeader I want to be able to extract operator name then to extract beginTime.

Next scenario ****extract the information which contains CllID then get its mesTypes and mesResults respectively ****

as the file contains number of with different CllID so I want the final result like this

 CllID   date           time        mesTypes    mesResults 

64446   2011-05-15    00:00:00      6132413       0

64446   2011-05-15    00:00:00      6132414       0

64446   2011-05-15    00:00:00      6132415       6

64447   2011-05-15    00:00:00      6132413       0

64447   2011-05-15    00:00:00      6132414       1

64447   2011-05-15    00:00:00      6132415       6

How could I achieve this ? Here is what I have tried so far:

import java.io._

import scala.xml.Node

object xml_parser {

  def main (args:Array[String]) = {
    val input_xmlFile = scala.xml.XML.loadFile("C:/Users/ss.xml")


    val fileHeader = input_xmlFile \ "fileHeader"
    val vendorName = input_xmlFile \ "fileHeader" \ "@operator"
    val dateTime = input_xmlFile \ "fileHeader" \  "infoCollec"   \"@beginTime"

    val date = dateTime.text.split("T")(0)
    val time = dateTime.text.split("T")(1).split("-")(0)

    val CcIds = (input_xmlFile \ "infoCollecData" \ "infoMes" \\ "mesTypes" )
    val cids = CcIds.text.split("\\s+").toList
    al CounterValues = (input_xmlFile  \ "infoCollecData" \\ "infoMes" \\ "mesValue" \\ "@meaObj")

    println(date);println(time);print(cids)
1
  • like wise i have lots of infomes which contains the mestypes, mesValue,mesResults. i am stuck here how i can apply If,Filter or any map function there. Commented Jun 3, 2016 at 10:07

2 Answers 2

2

May I suggest kantan.xpath? It seems like it should sort your problem rather easily.

Assuming your XML data is available in file data, you can write:

import kantan.xpath.implicits._

val xml = data.asUnsafeNode

// Date format to parse dates. Put in the right format.
// Note that this uses java.util.Date, you could also use the joda time module.
implicit val format = ???

// Extract the header data
xml.evalXPath[java.util.Date](xp"//fileheader/infocollec/@begintime")
xml.evalXPath[String](xp"//fileheader/@operator")

// Get the required infoMes nodes as a list, turn each one into whatever data type you need.
xml.evalXPath[List[Node]](xp"//infomes/mesvalue[contains(@measobjldn, 'CllID')]/..").map { node =>
    ...
}

Extracting the CllID bit is not terribly complicated with the right regular expression, you could either use the standard Scala Regex class or kantan.regex for something a bit more type safe but that might be overkill here.

Sign up to request clarification or add additional context in comments.

Comments

1

The following code can implement what you want according to your xml format

def main(args: Array[String]): Unit = {
    val inputFile = xml.XML.loadFile("C:/Users/ss.xml")
    val fileHeader = inputFile \ "fileHeader"
    val beginTime = fileHeader \"infoCollec"
    val res = beginTime.map(_.attribute("beginTime")).apply(0).get.text
    val dateTime = res.split("T")
    val date = dateTime(0)
    val time = dateTime(1).split("-").apply(0)

    val title = ("CllID", "date", "time", "mesTypes", "mesResults")
    println(s"${title._1}\t${title._2}\t\t${title._3}\t\t${title._4}\t${title._5}")

    val infoMesNodeList = (inputFile \\ "infoMes").filter{node => (node \ "mesValue").exists(_.attribute("measObjLdn").nonEmpty)}
    infoMesNodeList.foreach{ node =>
        val mesTypesList = (node \ "mesTypes").text.split(" ").map(_.toInt)
        (node \ "mesValue").foreach { node =>
            val mesResultsList = (node \ "mesResults").text.split(" ").map(_.toInt)
            val CllID = node.attribute("measObjLdn").get.text.split(",").apply(1).split("=").apply(1).toInt
            val res = (mesTypesList zip mesResultsList).map(item => (CllID, date, time, item._1, item._2))
            res.foreach(item => println(s"${item._1}\t${item._2}\t${item._3}\t${item._4}\t\t${item._5}"))
        }
   }
}

Notes: your xml file does not have the right format

1) miss close tag in the last line of the file

2) line 11, have a wrong tag , which should be

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.