rivet/xml_loader.py

76 lines
2.1 KiB
Python
Raw Permalink Normal View History

2023-11-24 17:14:13 +00:00
from __future__ import annotations
2024-03-24 10:33:34 +00:00
2023-11-24 17:14:13 +00:00
from typing import TYPE_CHECKING
2024-03-24 10:33:34 +00:00
from bs4 import BeautifulSoup
2023-11-24 17:14:13 +00:00
if TYPE_CHECKING:
from io import TextIOWrapper
2024-04-12 21:33:09 +00:00
2023-11-24 17:14:13 +00:00
class XMLLoader:
2024-04-12 21:33:09 +00:00
@staticmethod
2023-11-24 17:14:13 +00:00
def load(file_: TextIOWrapper) -> dict:
schema = {}
bs = BeautifulSoup(file_.read(), "xml")
structElmts = bs.findAll("structure")
structures = {}
for structElmt in structElmts:
structures[structElmt.get("id")] = XMLLoader.parseStructure(structElmt)
schema["structures"] = structures
return schema
2024-04-12 21:33:09 +00:00
@staticmethod
2023-11-24 17:14:13 +00:00
def parseStructure(structElmt: any) -> dict:
2024-04-12 21:33:09 +00:00
struct = {
"bits": structElmt.get("bits")
}
2023-11-24 17:14:13 +00:00
ranges = {}
rangeElmts = structElmt.findAll("range")
for rangeElmt in rangeElmts:
span = rangeElmt.get("end") + "-" + rangeElmt.get("start")
ranges[span] = XMLLoader.parseRange(rangeElmt)
struct["ranges"] = ranges
return struct
2024-04-12 21:33:09 +00:00
@staticmethod
2023-11-24 17:14:13 +00:00
def parseRange(rangeElmt: any) -> dict:
2024-04-12 21:33:09 +00:00
range_ = {
"name": rangeElmt.get("name")
}
2023-11-24 17:14:13 +00:00
desc = rangeElmt.find("description")
2024-04-12 21:33:09 +00:00
if desc is not None:
range_["description"] = desc.getText()
2023-11-24 17:14:13 +00:00
valuesElmt = rangeElmt.find("values")
if valuesElmt is not None:
range_["values"] = XMLLoader.parseValues(valuesElmt)
if rangeElmt.get("depends-on"):
range_["depends-on"] = rangeElmt.get("depends-on")
return range_
2024-04-12 21:33:09 +00:00
@staticmethod
2023-11-24 17:14:13 +00:00
def parseValues(valuesElmt: any) -> dict:
values = {}
caseElmts = valuesElmt.findAll("case")
for caseElmt in caseElmts:
val = caseElmt.get("value")
desc = caseElmt.getText()
struct = caseElmt.get("structure")
if struct:
values[val] = {
"description": desc,
"structure": struct
}
else:
values[val] = desc
2024-04-12 21:33:09 +00:00
return values