""" Модель для хранения информации об XML файле. """ import re from pathlib import Path from typing import List, Set, Optional from lxml import etree class XMLFileInfo: def __init__(self, file_path: str): self.file_path = Path(file_path) self.cadastral_numbers: Set[str] = set() def extract_cadastral_numbers(self) -> Set[str]: """Извлекает кадастровые номера из XML файла""" if not self.file_path.exists(): return set() try: # Парсим XML файл tree = etree.parse(str(self.file_path)) root = tree.getroot() # Используем улучшенный алгоритм извлечения return self._extract_cadastral_numbers_enhanced(root) except Exception as e: print(f"Ошибка при обработке файла {self.file_path}: {e}") return set() def _extract_cadastral_numbers_enhanced(self, root) -> Set[str]: """Улучшенный алгоритм извлечения кадастровых номеров""" cadastral_numbers = set() # 1. Поиск по известным тегам tags_to_search = ['cad_number', 'land_cad_number', 'cadastral_number', 'parcel_cad_number'] for tag in tags_to_search: elements = root.xpath(f".//{tag}") for elem in elements: if elem.text and self._is_valid_cadastral_number(elem.text): cadastral_numbers.add(elem.text.strip()) # 2. Поиск в атрибутах for elem in root.iter(): for attr_name, attr_value in elem.attrib.items(): if any(keyword in attr_name.lower() for keyword in ['cad', 'cadastral', 'кадастр']): if self._is_valid_cadastral_number(attr_value): cadastral_numbers.add(attr_value.strip()) # 3. Regex поиск по тексту text_content = etree.tostring(root, encoding='unicode', method='text') if text_content: regex_matches = re.findall(r'\d{1,2}:\d{1,2}:\d{6,8}:\d{1,5}', text_content) for match in regex_matches: if self._is_valid_cadastral_number(match): cadastral_numbers.add(match) self.cadastral_numbers = cadastral_numbers return cadastral_numbers def _is_valid_cadastral_number(self, text: str) -> bool: """Проверяет, является ли строка валидным кадастровым номером""" if not text: return False # Улучшенный паттерн для российских кадастровых номеров pattern = r'^\d{1,2}:\d{1,2}:\d{6,8}:\d{1,5}$' return bool(re.match(pattern, text.strip())) def __str__(self): return f"XML файл: {self.file_path.name}, номеров: {len(self.cadastral_numbers)}"