rivet/xml_loader.py

67 lines
2.0 KiB
Python
Raw 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
class XMLLoader:
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
def parseStructure(structElmt: any) -> dict:
struct = {}
struct["bits"] = structElmt.get("bits")
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
def parseRange(rangeElmt: any) -> dict:
range_ = {}
range_["name"] = rangeElmt.get("name")
desc = rangeElmt.find("description")
if desc is not None: range_["description"] = desc.getText()
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_
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
return values