File size: 4,854 Bytes
57cf043
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import logging
import re

from bs4 import BeautifulSoup

from components.parser.abbreviations import AbbreviationExtractor
from components.parser.xml.structures import ParsedText

logger = logging.getLogger(__name__)


class XMLTextParser:
    """
    Класс для парсинга текста из xml файлов.
    """

    def __init__(self, soup: BeautifulSoup):
        """
        Инициализация парсера.

        Args:
            soup: BeautifulSoup - суп, содержащий весь xml документ
        """
        self.soup = soup
        self.abbreviation_extractor = AbbreviationExtractor()
        self.abbreviations = []

    def parse(self) -> ParsedText:
        """
        Парсинг текстовой информации из xml файла.

        Returns:
            ParsedText - структура с текстом, полученным из xml файла
        """
        parsed_text = self._extract_text()
        
        # Извлекаем аббревиатуры из текста
        if parsed_text and parsed_text.content:
            text_content = parsed_text.to_text()
            self.abbreviations = self.abbreviation_extractor.extract_abbreviations_from_text(text_content)
            logger.debug(f"Extracted {len(self.abbreviations)} abbreviations from text")
            
        return parsed_text
        
    def get_abbreviations(self) -> list:
        """
        Возвращает список аббревиатур, извлеченных из текста.
        
        Returns:
            list: Список аббревиатур
        """
        return self.abbreviations

    def _extract_text(self) -> ParsedText:
        """
        Извлечение и очистка текста из XML.

        Returns:
            ParsedText - структура, содержащая очищенный текст
        """
        # Удаляем все таблицы
        for table in self.soup.find_all('w:tbl'):
            table.decompose()

        # Удаляем бинарные данные
        for bindata in self.soup.find_all('w:bindata'):
            bindata.decompose()

        # Удаляем элементы v:shape (изображения)
        for shape in self.soup.find_all('v:shape'):
            shape.decompose()

        # Удаляем заголовки документа
        doc_props = self.soup.find('o:documentproperties')
        if doc_props:
            doc_props.decompose()

        # Извлекаем абзацы (теги w:p)
        paragraphs = []
        for p_tag in self.soup.find_all('w:p'):
            # Собираем все текстовые элементы в этом абзаце
            paragraph_text_elements = []
            for text_tag in p_tag.find_all('w:t'):
                content = text_tag.get_text()
                
                # Пропускаем специальные элементы в фигурных скобках
                if content and '{' in content and '}' in content:
                    if '{КСС}' in content or content.startswith('{СС_'):
                        continue
                
                if content:
                    paragraph_text_elements.append(content)
            
            if paragraph_text_elements:
                # Объединяем текст этого абзаца
                paragraph_text = ' '.join(paragraph_text_elements)
                
                # Очистка текста абзаца
                paragraph_text = paragraph_text.replace('&', '&')
                paragraph_text = paragraph_text.replace('&lt;', '<')
                paragraph_text = paragraph_text.replace('&gt;', '>')
                paragraph_text = paragraph_text.replace('MS-Word', '')
                paragraph_text = paragraph_text.replace('См. документ в ', '')
                paragraph_text = paragraph_text.replace(
                    '------------------------------------------------------------------', ''
                )
                
                # Удаление фигурных скобок и их содержимого
                paragraph_text = re.sub(
                    r'\{[\.\,\#\:\=A-Za-zа-яА-Я\d\/\s\"\-\/\?\%\_\.\&\$]+\}', '', paragraph_text
                )
                
                # Форматирование текста абзаца
                paragraph_text = re.sub(r'[\t ]+', ' ', paragraph_text)
                paragraph_text = paragraph_text.strip()
                
                if paragraph_text:  # Добавляем только непустые абзацы
                    paragraphs.append(paragraph_text)

        return ParsedText(content=paragraphs)