Вот вам для примера, что выдает Клод 4. Проверять не стал, но интересна ваша проверка этого ответа.
Скрытый текст
Проблема в том, что xmltodict по умолчанию не сохраняет информацию о том, что содержимое было в CDATA секции. Параметр force_cdata=True заставляет парсер обрабатывать все текстовые узлы как потенциальные CDATA, но не сохраняет оригинальную структуру.
Вот несколько решений:
Решение 1: Использование process_namespaces=False и strip_whitespace=False
import xmltodict
data = """<node1>
<node2 id='test'><![CDATA[test]]></node2>
<node3 id='test'>test</node3>
</node1>"""
# Парсинг с сохранением CDATA информации
parsed = xmltodict.parse(data, process_namespaces=False, strip_whitespace=False)
print("Parsed:", parsed)
# Для восстановления CDATA нужно вручную пометить узлы
parsed['node1']['node2']['#cdata-section'] = parsed['node1']['node2'].pop('#text')
print("Modified:", parsed)
print("\nUnparsed:")
print(xmltodict.unparse(parsed, pretty=True))
Решение 2: Кастомная обработка с отслеживанием CDATA
import xmltodict
import xml.etree.ElementTree as ET
def preserve_cdata_parse(xml_string):
# Сначала найдем все CDATA секции
cdata_nodes = {}
# Простой способ найти CDATA (для более сложных случаев нужен proper XML parser)
import re
cdata_pattern = r'<([^>]+)><!\[CDATA\[(.*?)\]\]></\1>'
matches = re.findall(cdata_pattern, xml_string, re.DOTALL)
for match in matches:
tag_info = match[0]
cdata_content = match[1]
# Сохраняем информацию о том, что это CDATA
if 'id=' in tag_info:
id_match = re.search(r"id='([^']*)'", tag_info)
if id_match:
cdata_nodes[id_match.group(1)] = cdata_content
# Парсим XML
parsed = xmltodict.parse(xml_string)
# Восстанавливаем CDATA секции
def restore_cdata(obj, cdata_map):
if isinstance(obj, dict):
for key, value in obj.items():
if isinstance(value, dict) and '@id' in value and value['@id'] in cdata_map:
# Заменяем #text на #cdata-section
if '#text' in value:
value['#cdata-section'] = value.pop('#text')
restore_cdata(value, cdata_map)
elif isinstance(obj, list):
for item in obj:
restore_cdata(item, cdata_map)
restore_cdata(parsed, cdata_nodes)
return parsed
# Использование
data = """<node1>
<node2 id='test'><![CDATA[test]]></node2>
<node3 id='test'>test</node3>
</node1>"""
parsed = preserve_cdata_parse(data)
print("Parsed with CDATA preservation:", parsed)
print("\nUnparsed:")
print(xmltodict.unparse(parsed, pretty=True))
Решение 3: Использование lxml (более надежное)
from lxml import etree
import xmltodict
def parse_with_cdata_preservation(xml_string):
# Используем lxml для более точного парсинга
parser = etree.XMLParser(strip_cdata=False)
root = etree.fromstring(xml_string.encode('utf-8'), parser)
def element_to_dict(element):
result = {}
# Добавляем атрибуты
if element.attrib:
for key, value in element.attrib.items():
result[f'@{key}'] = value
# Проверяем текстовое содержимое
if element.text:
# Проверяем, является ли это CDATA
original_xml = etree.tostring(element, encoding='unicode')
if '<![CDATA[' in original_xml:
result['#cdata-section'] = element.text
else:
result['#text'] = element.text
# Обрабатываем дочерние элементы
for child in element:
child_dict = element_to_dict(child)
if child.tag in result:
if not isinstance(result[child.tag], list):
result[child.tag] = [result[child.tag]]
result[child.tag].append(child_dict)
else:
result[child.tag] = child_dict
return result
return {root.tag: element_to_dict(root)}
# Использование
data = """<node1>
<node2 id='test'><![CDATA[test]]></node2>
<node3 id='test'>test</node3>
</node1>"""
parsed = parse_with_cdata_preservation(data)
print("Parsed:", parsed)
print("\nUnparsed:")
print(xmltodict.unparse(parsed, pretty=True))
Основная проблема в том, что xmltodict не различает CDATA и обычный текст на уровне представления данных. Вам нужно либо вручную помечать узлы, либо использовать более сложную логику для автоматического определения CDATA секций.
Когда синьоры работают с инструментами вроде Cursor или Copilot, это выглядит как магия. Они могут создать целую функциональность за минуты, включая тесты и документацию. Но если присмотреться, заметно ключевое: они не просто позволяют ИИ генерировать код. Они постоянно рефакторят сгенерированный код. Они добавляют обработку ошибок, ловят edge кейсы, которые ИИ пропустил, усиливают типизацию и интерфейсы, а также ставят под сомнение архитектурные решения ИИ.Иными словами, они применяют годы опыта, чтобы формировать и ограничивать вывод ИИ.ИИ ускоряет реализацию, но их экспертиза обеспечивает поддержку проекта.
Спустя год или два на этом алгоритме модели дообучаются и ...
Одна из гипотез в том, что станут востребованы "кастомные" приложения. Одна команда\бизнес - несколько приложений созданных специально под потребности команды\бизнеса. В этом варианте количество занятых в индустрии может вырасти.
Аккуратнее... Побочные эффекты: Возможны снижение либидо, эректильная дисфункция, снижение объема эякулята, депрессия. В редких случаях наблюдаются длительные побочные эффекты, даже после прекращения приема (пост-финастеридный синдром).
Спасибо за статью, неожиданно много расходов. Только не понял вот про это
Тут же меня часто спрашивают, сколько вообще срок службы сервера (это который должен на промотарифах окупаться примерно 17 лет, как в ипотеке). Так вот, лучше не рассчитывать больше чем на пять лет стабильной работы. При этом на третий год там надо будет заменить все диски, иначе есть шансы разом сломать рейды.
Было бы прикольно написать приложение под все платформы (например на flutter) и использовать IPFS (InterPlanetary File System).
И простейшая логика: 1. В приложении мы можем скачивать книги, например первые 50 книг просто так. 2. Далее чтобы скачивать книги мы должны быть на раздаче скачанных книг не менее Х времени.
При такой схеме сервер (нода) будет работать только как поддерживающее файловое хранилище для неактивных раздач + так используется приложение, то оно устойчиво к цензуре.
Не думаю, что такое сложно написать, если запилить open source, то будет самоподдерживающаяся система.
И далее в эту систему можно другие файлы заливать - научные статьи и т.п.
14. Да живи ты хоть три тысячи лет, хоть тридцать тысяч, только помни, что человек никакой другой жизни не теряет, кроме той, которой жив; и живет лишь той, которую теряет. Вот и выходит одно на одно длиннейшее и кратчайшее. Ведь настоящее у всех равно, хотя и не равно то, что утрачивается; так оказывается каким-то мгновением то, что мы теряем, а прошлое и будущее терять нельзя, потому что нельзя ни у кого отнять то, чего у него нет. Поэтому помни две вещи. Первое, что все от века единообразно и вращается по кругу, и безразлично, наблюдать ли одно и то же сто лет, двести или бесконечно долго. А другое, что и долговечнейший и тот, кому рано умирать, теряет ровно столько же. Ибо настоящее — единственное, чего они могут лишиться, раз это и только это, имеют, а чего не имеешь, то нельзя потерять.
Далее Марка Аврелия логично почитать наверное, лично мне он проще воспринимался.
Gemini API. Мощный инструмент для детального контроля над анимацией виджетов. Он не только открывает новые возможности для творчества, но и повышает качество взаимодействия с пользователем в приложениях Flutter.
Спасибо, ценная статья. Использовал в проекте родную интернализацию, но, по мере роста проекта, пришлось самому писать скрипты для получения данных из систем перевода и синхронизации с сайтом. Смотрел в сторону easy_localization, но предложенный вами вариант нравится больше.
Это в настройках доступа к ключу в самом Google Cloud решается. Например - ваше приложение при публикации подписывается цифровой подписью. https://docs.flutter.dev/deployment/android#signing-the-app Вы можете создать правило, что доступ к API умеют только android приложения с таким-то Certificate fingerprint (SHA-1).
Через 10+15 лет эти девочки-инстаблонгеры обрастут жиром и морщинами и внезапно никому будет больше не нужны, останутся у разбитого корыта
Не все так линейно и просто. Это такая же, быть может в будущем, даже более востребованная чем программирование, профессия. У нас мозг уже не сможет решать сложные задачи и осваивать условное квантовое программирование. А девочки с морщинами будут вести аккаунты как оставаться молодыми, как развлекаться в старости, как ... и т.п.
Вот вам для примера, что выдает Клод 4. Проверять не стал, но интересна ваша проверка этого ответа.
Скрытый текст
Проблема в том, что
xmltodict
по умолчанию не сохраняет информацию о том, что содержимое было в CDATA секции. Параметрforce_cdata=True
заставляет парсер обрабатывать все текстовые узлы как потенциальные CDATA, но не сохраняет оригинальную структуру.Вот несколько решений:
Решение 1: Использование
process_namespaces=False
иstrip_whitespace=False
Решение 2: Кастомная обработка с отслеживанием CDATA
Решение 3: Использование lxml (более надежное)
Самое простое решение для вашего случая:
Это даст вам:
Основная проблема в том, что
xmltodict
не различает CDATA и обычный текст на уровне представления данных. Вам нужно либо вручную помечать узлы, либо использовать более сложную логику для автоматического определения CDATA секций.Когда синьоры работают с инструментами вроде Cursor или Copilot, это выглядит как магия. Они могут создать целую функциональность за минуты, включая тесты и документацию. Но если присмотреться, заметно ключевое: они не просто позволяют ИИ генерировать код. Они постоянно рефакторят сгенерированный код. Они добавляют обработку ошибок, ловят edge кейсы, которые ИИ пропустил, усиливают типизацию и интерфейсы, а также ставят под сомнение архитектурные решения ИИ.Иными словами, они применяют годы опыта, чтобы формировать и ограничивать вывод ИИ.ИИ ускоряет реализацию, но их экспертиза обеспечивает поддержку проекта.
Спустя год или два на этом алгоритме модели дообучаются и ...
Одна из гипотез в том, что станут востребованы "кастомные" приложения. Одна команда\бизнес - несколько приложений созданных специально под потребности команды\бизнеса.
В этом варианте количество занятых в индустрии может вырасти.
Новости: скоро нейросети заменят программистов, нужно только точно и подробно поставить задачу и они все сделают сами.
Программист: фух, можно не бояться.
Аккуратнее...
Побочные эффекты: Возможны снижение либидо, эректильная дисфункция, снижение объема эякулята, депрессия. В редких случаях наблюдаются длительные побочные эффекты, даже после прекращения приема (пост-финастеридный синдром).
Спасибо за статью, неожиданно много расходов.
Только не понял вот про это
Тут же меня часто спрашивают, сколько вообще срок службы сервера (это который должен на промотарифах окупаться примерно 17 лет, как в ипотеке). Так вот, лучше не рассчитывать больше чем на пять лет стабильной работы. При этом на третий год там надо будет заменить все диски, иначе есть шансы разом сломать рейды.
Почему диски всего на три года?
Было бы прикольно написать приложение под все платформы (например на flutter) и использовать IPFS (InterPlanetary File System).
И простейшая логика:
1. В приложении мы можем скачивать книги, например первые 50 книг просто так.
2. Далее чтобы скачивать книги мы должны быть на раздаче скачанных книг не менее Х времени.
При такой схеме сервер (нода) будет работать только как поддерживающее файловое хранилище для неактивных раздач + так используется приложение, то оно устойчиво к цензуре.
Не думаю, что такое сложно написать, если запилить open source, то будет самоподдерживающаяся система.
И далее в эту систему можно другие файлы заливать - научные статьи и т.п.
Спасибо, классный перевод.
увы, уже нет
Далее Марка Аврелия логично почитать наверное, лично мне он проще воспринимался.
хм )
В растительном масле 0% трансжиров. Даже в маргарине старого типа столько нет (новые делают без трансжиров тоже)
Спасибо, интересно.
Вот тут опечатка
английского слова «serf»
, правильно surf.Интересно, а по общему размеру есть ограничения? Например если отправить 900 000 сообщений по 4 гига?
Спасибо, ценная статья.
Использовал в проекте родную интернализацию, но, по мере роста проекта, пришлось самому писать скрипты для получения данных из систем перевода и синхронизации с сайтом.
Смотрел в сторону
easy_localization
, но предложенный вами вариант нравится больше.Это в настройках доступа к ключу в самом Google Cloud решается.
Например - ваше приложение при публикации подписывается цифровой подписью.
https://docs.flutter.dev/deployment/android#signing-the-app
Вы можете создать правило, что доступ к API умеют только android приложения с таким-то Certificate fingerprint (SHA-1).
Спасибо, интересно.
— регистрируемся по индивидуальной трудовой деятельности
Выше привели ссылку для регистрации в налоговой. То есть можно зарегистрироваться не находясь в стране?
Через 10+15 лет эти девочки-инстаблонгеры обрастут жиром и морщинами и внезапно никому будет больше не нужны, останутся у разбитого корыта
Не все так линейно и просто.
Это такая же, быть может в будущем, даже более востребованная чем программирование, профессия.
У нас мозг уже не сможет решать сложные задачи и осваивать условное квантовое программирование.
А девочки с морщинами будут вести аккаунты как оставаться молодыми, как развлекаться в старости, как ... и т.п.