1

In scala, is there a simple way to get all elements of an XML doc represented as a list?

My code:

object HelloWorld {

    def main(args: Array[String]) {
    val res="76561193756669631"
    val url=("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=XXXYYYZZZ&steamids="+res+"&format=xml")
    val str = scala.io.Source.fromURL(url.toString,"utf-8").mkString
    val x=xml.XML.loadString(str)
    var r=(x\\"steamid").mkString
    r=r.replaceAll("""<[a-zA-Z0-9/]*?>""","")
    println(r)

}}

retrieves the xml:

<response>
<players>
<player>
<steamid>76561193756669631</steamid>
<communityvisibilitystate>3</communityvisibilitystate>
<personaname>*******je01</personaname>
<lastlogoff>1320236285</lastlogoff>
<profileurl>
http://steamcommunity.com/profiles/76561193756669631/
</profileurl>
<avatar>
https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb.jpg
</avatar>
<avatarmedium>
https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_medium.jpg
</avatarmedium>
<avatarfull>
https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg
</avatarfull>
<personastate>0</personastate>
<primaryclanid>103582791429521408</primaryclanid>
<timecreated>1320224696</timecreated>
<personastateflags>0</personastateflags>
</player>
</players>
</response>

and outputs the steamid because I hardcoded it in. Is there a way to oputput a list of all the elements and their values?

My goal:

steamid: 76561193756669631
communityvisibilitystate: 3
personaname: *******je01
....

1 Answer 1

1

Here what you have to do to get those elements:

  import scala.xml._
  val x = <response>
    <players>
      <player>
        <steamid>76561193756669631</steamid>
        <communityvisibilitystate>3</communityvisibilitystate>
        <personaname>*******je01</personaname>
        <lastlogoff>1320236285</lastlogoff>
        <profileurl>
          http://steamcommunity.com/profiles/76561193756669631/
        </profileurl>
        <avatar>
          https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb.jpg
        </avatar>
        <avatarmedium>
          https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_medium.jpg
        </avatarmedium>
        <avatarfull>
          https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg
        </avatarfull>
        <personastate>0</personastate>
        <primaryclanid>103582791429521408</primaryclanid>
        <timecreated>1320224696</timecreated>
        <personastateflags>0</personastateflags>
      </player>
    </players>
  </response>

  val allNodes = x \\ "response" \\ "players" \\ "player"  flatMap(_.child)
  allNodes.foreach(n => println(s"label: ${n.label} -> text: ${n.text}"))

first find the all players then get the attributes you need. And you will get the following(some doesn't have any text):

label: #PCDATA -> text: 

label: steamid -> text: 76561193756669631
label: #PCDATA -> text: 

label: communityvisibilitystate -> text: 3
label: #PCDATA -> text: 

label: personaname -> text: *******je01
label: #PCDATA -> text: 

label: lastlogoff -> text: 1320236285
label: #PCDATA -> text: 

label: profileurl -> text: 
          http://steamcommunity.com/profiles/76561193756669631/

label: #PCDATA -> text: 

label: avatar -> text: 
          https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb.jpg

label: #PCDATA -> text: 

label: avatarmedium -> text: 
          https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_medium.jpg

label: #PCDATA -> text: 

label: avatarfull -> text: 
          https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/fe/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg

label: #PCDATA -> text: 

label: personastate -> text: 0
label: #PCDATA -> text: 

label: primaryclanid -> text: 103582791429521408
label: #PCDATA -> text: 

label: timecreated -> text: 1320224696
label: #PCDATA -> text: 

label: personastateflags -> text: 0
label: #PCDATA -> text: 
Sign up to request clarification or add additional context in comments.

3 Comments

That did exactly what I wanted, but I cant figure out where the label: #PCDATA -> text: is coming from. When I view the source I dont see it at all. Is it hidden in the XML somehow? If so, can I just filter it out?
here: println(s"label: ${n.label} -> text: ${n.text}") it's sugar for strings in Scala. allNodes is NodeSeq which you can iterate over it
The #PCDATA you see is the text between a close tag and a open tag. In the example there are only white characters (spaces and new lines), but if you put some text between let's say </steamid> and <communityvisibilitystate>, you will see it as #PCDATA in the output. You can filter it out with this: x \\ "response" \\ "players" \\ "player" flatMap(_.child) filter(!_.isAtom)

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.