72 lines
3.1 KiB
Python
72 lines
3.1 KiB
Python
"""
|
||
Модель для хранения информации об 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)}"
|