-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse.py
More file actions
82 lines (77 loc) · 3.38 KB
/
parse.py
File metadata and controls
82 lines (77 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
from classes.driver import Driver
from classes.lap import Lap
from classes.sessionresult import SessionResult
from classes.event import Event
from classes.parseable import Parseable
from xml.etree import ElementTree as ET
from typing import List
from pathlib import Path
from nameparser import HumanName
def parseXML(xmlPath: str) -> SessionResult:
from xml.etree import ElementTree as ET
tree = ET.parse(xmlPath)
root = tree.getroot()
result: SessionResult = SessionResult()
result.Session = "Practise1"
result.FileName = xmlPath
sessionKeys = ["Race", "Practise1", "Qualify"]
for session in sessionKeys:
if len(root.findall('.//' + session)) == 1:
result.Session = session
break
parseObject(result, root, True)
censoredNames = {}
for driverNode in root.findall('.//Driver'):
driver = Driver()
parseObject(driver, driverNode, False)
for lapNode in driverNode.findall('.//Lap'):
lap = Lap()
parseObject(lap, lapNode, False)
lap.Duration = lap.S1 + lap.S2 + lap.S3
driver.Laps.append(lap)
humanName = HumanName(driver.Name)
if len(humanName.last) > 0:
censoredNames[driver.Name] = humanName.first + " " + humanName.last[0]
driver.Name = humanName.first + " " + humanName.last[0]
result.Drivers.append(driver)
for raw in root.findall('.//Stream/Chat') + root.findall('.//Stream/Command') + root.findall('.//Stream/Sector') + root.findall('.//Stream/Incident'):
e = Event()
e.Et = raw.attrib.get("et")
e.Text = raw.text
e.Type = raw.tag
for oldName, newName in censoredNames.items():
e.Text = e.Text.replace(oldName, newName)
result.Stream.append(e)
result.Name = Path(xmlPath).name.replace(".xml","")
result.Drivers = sorted(result.Drivers, key= lambda d:d.ClassPosition)
return result
def parseObject(source: Parseable, rootNode, useFirst: bool):
for propKey in dir(source):
if "__" not in propKey and "__TRANSLATION__" != propKey:
keyToSearch = source.__TRANSLATION__[propKey] if propKey in source.__TRANSLATION__ else propKey
# try to search for child notes matching
transferTagText(rootNode,'.//'+keyToSearch,source,propKey, useFirst)
# try to search for attributes
for attributeKey, attributeValue in rootNode.attrib.items():
if propKey in source.__TRANSLATION__ and source.__TRANSLATION__[propKey] == attributeKey:
setValue(source, propKey, attributeValue)
def setValue(source, propKey, newValue):
initValue = getattr(source, propKey)
newParsedValue = newValue.strip()
if type(initValue) is float:
newParsedValue = float(newValue.replace(",",".").replace("--.---","0.0"))
if type(initValue) is str:
newParsedValue = str(newValue.strip())
if type(initValue) is int:
newParsedValue = int(newValue)
if type(initValue) is type(newParsedValue):
setattr(source, propKey, newParsedValue)
def transferTagText(rootNode, xPath: str, targetObject: Parseable, targetProperty: str, useFirst: bool):
results = rootNode.findall(xPath)
if len(results) == 1:
setValue(targetObject, targetProperty, rootNode.findall(xPath)[0].text)
if len(results) > 1:
if not useFirst:
raise Exception("Unclear matches: " + targetProperty + " matches: " + str(len(results)))
else:
setValue(targetObject, targetProperty, rootNode.findall(xPath)[0].text)