import os from lxml import etree def make_absolute_path(path, base_path): if not os.path.isabs(path) and os.path.isdir(base_path): try: return os.path.abspath(os.path.join(base_path, path)) except Exception: pass # На случай сбоя в os.path.join или abspath elif os.path.isabs(path): return os.path.abspath(path) else: return path def make_relative_path(abs_path, base_path): abs_path = os.path.abspath(abs_path) base_path = os.path.abspath(base_path) # Разбиваем на списки директорий abs_parts = abs_path.split(os.sep) base_parts = base_path.split(os.sep) # Проверяем, является ли base_path настоящим префиксом пути (по папкам) if abs_parts[:len(base_parts)] == base_parts: rel_parts = abs_parts[len(base_parts):] return "/".join(rel_parts) # Иначе пробуем relpath try: return os.path.relpath(abs_path, base_path).replace("\\", "/") except Exception: return abs_path.replace("\\", "/") def indent_xml(elem, level=0): # Убираем strip() — они медленные, и текст мы всё равно перезаписываем i = "\n" + level * " " if len(elem): elem.text = elem.text or i + " " for child in elem: indent_xml(child, level + 1) elem[-1].tail = elem[-1].tail or i else: elem.tail = elem.tail or i def fwrite(root, xml_full_path): #indent_xml(root) #ET.ElementTree(root).write(xml_full_path, encoding="utf-8", xml_declaration=True) rough_string = etree.tostring(root, encoding="utf-8") parsed = etree.fromstring(rough_string) with open(xml_full_path, "wb") as f: f.write(etree.tostring(parsed, pretty_print=True, encoding="utf-8", xml_declaration=True)) def safe_parse_xml(xml_path): if not xml_path or not os.path.isfile(xml_path): print(f"Файл '{xml_path}' не найден или путь пустой") return None, None try: if os.path.getsize(xml_path) == 0: return None, None tree = etree.parse(xml_path) root = tree.getroot() return root, tree except etree .XMLSyntaxError as e: print(f"Ошибка парсинга XML файла '{xml_path}': {e}") return None, None except Exception as e: print(f"Неожиданная ошибка при чтении XML файла '{xml_path}': {e}") return None, None