0

I using ElementTree to try and extract a number of values from an XML.

Here is a sample of the xml:-

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE playerstats>
<playerstats>
<steamID>76561197960964581</steamID>
<gameName>Team Fortress 2</gameName>
<stats>
    <stat>
        <name>Scout.accum.iNumberOfKills</name>
        <value>1777</value>
    </stat>
    <stat>
        <name>Scout.accum.iPlayTime</name>
        <value>247469</value>
    </stat>
    <stat>
        <name>Scout.accum.iPointCaptures</name>
        <value>641</value>
    </stat>
    <stat>
        <name>Soldier.accum.iNumberOfKills</name>
        <value>1270</value>
    </stat>
    <stat>
        <name>Soldier.accum.iPlayTime</name>
        <value>94649</value>
    </stat>
    <stat>
        <name>Spy.accum.iNumberOfKills</name>
        <value>7489</value>
    </stat>
    <stat>
        <name>Spy.accum.iPlayTime</name>
        <value>1110582</value>
    </stat>
</stats>
</playerstats>

There is a lot more, but this is just a sample.

I want to extract and sum all the values relating to "*.accum.iPlayTime", to calculate a total play time. Star implying all classes (e.g. scout, soldier, etc).

My code so far (including some of my attempts):-

playerStatsKISA = urllib2.urlopen('http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/?appid=440&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&steamid=xxxxxxxxxxxxxxxxx&format=xml')
statsTF2 = playerStatsTF2.read()
theStatsTF2 = ET.fromstring(statsTF2)

totalTimesTF2 = theStatsKISA.findtext("Scout.accum.iPlayTime") # Didn't find anything
print totalTimesKISA

totalTimesTF2 = theStatsKISA.findall("./stats/stat/name") 
for indiv in totalTimesTF2: # Another failed attempt
    print indiv.attrib # didn't extract anything, I gather because the text I'm after is not an attribute but a value?
    if indiv.attrib == 'Scout.accum.iPlayTime':
        print "got it" # would extract value here, but it would be long winded to do this then try and extract the next value I'm actually after.

I was going with the idea of acquiring the value from each class then summing it. Though I gather there is probably a away to get all the value in one foul swoop using a * for the TF2 class name, but I was going to do that after I first worked out how to get the value from the tag following one that contained the value I needed.

Hope this made sense.

Thanks.

2 Answers 2

3

Use text attribute:

root = ET.fromstring(statsTF2)
for stat in root.findall("./stats/stat"):
    if stat.find('name').text.endswith('.accum.iPlayTime'):
        print stat.find('value').text

prints (given the xml in the question):

247469
94649
1110582

Using lxml with XPath:

import lxml.etree as ET

root = ET.fromstring(statsTF2)
for text in root.xpath('./stats/stat[name[contains(text(), ".accum.iPlayTime")]]/value/text()'):
    print text
Sign up to request clarification or add additional context in comments.

Comments

2

This should work

totalTime = 0
root = ET.fromstring(statsTF2)
for stat in root.findall("./stats/stat"):
    if stat.find('name').text.endswith('accum.iPlayTime'):
        totalTime+=int(stat.find('value').text)


totalTime
>>> 1452700

1 Comment

Thanks for the answer and for how to accumulate the values.

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.