APED_Device/xml_reader.py
2021-01-04 23:10:02 +01:00

102 lines
3.4 KiB
Python

from lxml import etree
class Xml_reader:
""" reader for the XML configuration """
def __init__(self, xml_path: str, xsd_path: str):
"""inits the reader
Args:
xml_path (str): the path to the XML file
xsd_path (str): the path to the XSD file
Raises:
SyntaxError: validity of XML file is checked with the XSD file
"""
#check the XML for validity using the XSD file
if not self.validate(xml_path,xsd_path):
raise SyntaxError('the XML config file has an invalid syntax')
self.set_root(xml_path)
def set_root(self, xml_path: str):
self.root = etree.parse(xml_path).getroot()
def validate(self, xml_path: str, xsd_path: str) -> bool:
"""validates a XML by using a XSD file
Args:
xml_path (str): the path to the XML file
xsd_path (str): the path to the XSD file
Returns:
bool: result of the validation
"""
xml_schema = etree.XMLSchema(etree.parse(xsd_path))
return xml_schema.validate(etree.parse(xml_path))
def get_device_names(self) -> list:
"""lists all the device names from the config XML
Returns:
list: all device names as strings
"""
return [device.get("name") for device in self.root.findall('Device')]
def get_value_info(self,device_name: str) -> dict:
"""returns the value information for a given device
Args:
device_name (str): the name of a device
Returns:
dict: {'type','unit','offset','factor'}
Raises:
NameError: device_name will be checked against the config XML
"""
#check if a device exists in the config XML
if self.root.find("Device[@name='%s']" % device_name) is None:
raise NameError("unknown device %s" % device_name)
value_info = self.root.find(
"Device[@name='%s']/ValueInfo" % device_name)
#format the output
return {
'type': value_info.get('type'),
'unit': value_info.get('unit'),
'offset': None if value_info.find("Offset") is None
else value_info.find("Offset").text,
'factor': None if value_info.find("Factor") is None
else value_info.find("Factor").text,
}
def get_port(self,device_name:str) -> dict:
"""returns the information about a port of a given device
Args:
device_name (str): the name of a device
Returns:
dict: {'protocol', [list: pins]}
Raises:
NameError: device_name will be checked against the config XML
"""
if self.root.find("Device[@name='%s']" % device_name) is None:
raise NameError("unknown device %s" % device_name)
port = self.root.find(
"Device[@name='%s']/Port" % device_name)
return {
'protocol': port.get('protocol'),
'pins': [
pin.text for pin in self.root.findall(
"Device[@name='%s']/Port/Pin" % device_name
)
]
}
# ##test
# xml_reader = Xml_reader('XML/Test.xml','XML/config.xsd')
# print(xml_reader.get_device_names)
# print(xml_reader.get_value_info("example"))
# print(xml_reader.get_port("example"))
# print(xml_reader.get_value_info("sensorarray"))
# print(xml_reader.get_port("sensorarray"))