Files
kadastr14/models/xml_file_info.py

72 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Модель для хранения информации об 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)}"