Хранение escape-кодов VT100 в файле XML
Я пишу программу на Python, которая регистрирует взаимодействие с терминалом (по аналогии со скриптовой программой), и я хотел бы сохранить журнал в формате XML.
Проблема заключается в том, что взаимодействие с терминалом включает коды выхода VT100. Python не жалуется, если я записываю данные в файл в кодировке UTF-8, например:
...
pid, fd = pty.fork()
if pid==0:
os.execvp("bash",("bash","-l"))
else:
# Lots of TTY-related stuff here
# see http://groups.google.com/group/comp.lang.python/msg/de40b36c6f0c53cc
fout = codecs.open("session.xml", encoding="utf-8", mode="w")
fout.write('<?xml version="1.0" encoding="UTF-8"?>\n')
fout.write("<session>\n")
...
r, w, e = select.select([0, fd], [], [], 1)
for f in r:
if f==fd:
fout.write("<entry><![CDATA[")
buf = os.read(fd, 1024)
fout.write(buf)
fout.write("]]></entry>\n")
else:
....
fout.write("</session>")
fout.close()
Этот сценарий "работает" в том смысле, что он записывает файл на диск, но полученный файл не является правильным utf-8, что приводит к тому, что парсеры XML, такие как etree, блокируют escape-коды.
Один из способов справиться с этим - сначала отфильтровать escape-коды. Но если возможно сделать что-то подобное, когда сохраняются управляющие коды и полученный файл может быть проанализирован такими инструментами XML, как etree?
3 ответа
Ваша проблема не в том, что управляющие коды не являются правильными UTF-8, они просто ASCII ESC
и друзья не являются правильными символами XML, даже внутри раздела CDATA.
Единственными действительными символами XML в XML 1.0, значения которых меньше U+0020, являются U+0009 (табуляция), U+000A (новая строка) и U+000D (возврат каретки). Если вы хотите записывать вещи, связанные с другими кодами, такими как escape (U+001B), вам придется каким-то образом их избегать. Другого варианта нет.
Как сказал Чарльз, большинство управляющих кодов вообще не могут быть включены в файл XML 1.0.
Однако, если вы можете справиться с требованиями XML 1.1, вы можете использовать их там. Они не могут быть включены как необработанные символы, но могут быть ссылками на символы. например:

потому что вы не можете писать ссылки на символы в разделе CDATA (они будут просто интерпретированы как ampersand-hash-...), вам придется потерять <![CDATA[
обертка и ручной побег &<>
символы для их ссылок на сущности.
Обратите внимание, что вы должны сделать это в любом случае: разделы CDATA не освобождают вас от ответственности за экранирование текста, потому что они потерпят неудачу, если текст внутри содержит последовательность ]]>
, (Так как вам все равно всегда приходится убегать, в большинстве случаев это делает разделы CDATA бесполезными.)
XML 1.1 более мягок в отношении управляющих кодов, но не все его поддерживают, и вы все равно не можете включить символ NUL (�
). В общем случае не стоит включать управляющие символы в XML. Вы можете использовать специальную схему кодирования для размещения двоичного кода; base-64 популярна, но не очень удобочитаема. Альтернативы могут включать использование случайных символов из Частной области использования в качестве заменителей, если только ваше собственное приложение будет обрабатывать файлы, или кодировать их как элементы (например, <esc color="1"/>
).
Вы пытались поместить свои данные в раздел CDATA? это должно помешать парсеру попытаться прочитать содержимое тега.