Spaces:
Sleeping
Sleeping
import os | |
from bs4 import BeautifulSoup | |
from components.parser.xml.constants import ( | |
ACTUAL_STATUSES, | |
EXCLUDE_OWNERS, | |
NAME_TAG, | |
OWNER_TAGS, | |
STATUS_TAG, | |
USEFUL_STATUSES, | |
) | |
from components.parser.xml.structures import ParsedXML | |
class XMLInfoParser: | |
""" | |
Класс для парсинга основной информации из xml файлов. | |
""" | |
def __init__(self, soup: BeautifulSoup, filepath: os.PathLike): | |
""" | |
Инициализация парсера. | |
Args: | |
soup: BeautifulSoup - суп, содержащий xml документ | |
filepath: os.PathLike - путь к файлу | |
""" | |
self.filepath = filepath | |
self.soup = soup | |
def parse(self) -> ParsedXML | None: | |
""" | |
Парсинг основной информации о xml файле. | |
Returns: | |
ParsedXML - информация о xml файле | |
""" | |
status = self._extract_info_value(STATUS_TAG) | |
owner = self._extract_info_recurse(OWNER_TAGS, EXCLUDE_OWNERS) | |
name = self._extract_info_value(NAME_TAG) | |
if (name == '') and (status == '') and (owner == ''): | |
status = ACTUAL_STATUSES[0] | |
owner = '-' | |
name = self.filepath.stem | |
if status not in USEFUL_STATUSES: | |
return None | |
return ParsedXML(status=status, owner=owner, name=name, filename=self.filepath) | |
def _extract_info_value(self, key: str) -> str: | |
""" | |
Извлечение значения из xml по тегу с использованием BeautifulSoup. | |
Args: | |
key: str - тег, по которому будет производиться поиск. Либо название документа, либо статус, либо владелец | |
Returns: | |
str - значение статуса, владельца или названия документа | |
""" | |
# Ищем тег в супе | |
key_tag = self.soup.find(string=key) | |
if not key_tag: | |
return '' | |
# Ищем следующий текстовый тег после ключевого | |
next_tag = key_tag.find_next('w:t') | |
if not next_tag: | |
return '' | |
return next_tag.get_text() | |
def _extract_info_recurse( | |
self, | |
keys: list[str], | |
excluding_values: list[str] | None = None, | |
) -> str: | |
""" | |
Извлечение значения из xml по нескольким тегам с использованием BeautifulSoup. | |
Args: | |
keys: list[str] - список тегов, по которым будет производиться поиск | |
excluding_values: list[str] | None - список значений, которые нужно исключить из результата | |
Returns: | |
str - значение статуса, владельца или названия документа | |
""" | |
result = [] | |
for key in keys: | |
value = self._extract_info_value(key) | |
if excluding_values and (value in excluding_values): | |
continue | |
if value: | |
result.append(value) | |
return '/'.join(reversed(result)) | |