Хранение 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, вы можете использовать их там. Они не могут быть включены как необработанные символы, но могут быть ссылками на символы. например:

&#27;

потому что вы не можете писать ссылки на символы в разделе CDATA (они будут просто интерпретированы как ampersand-hash-...), вам придется потерять <![CDATA[ обертка и ручной побег &<> символы для их ссылок на сущности.

Обратите внимание, что вы должны сделать это в любом случае: разделы CDATA не освобождают вас от ответственности за экранирование текста, потому что они потерпят неудачу, если текст внутри содержит последовательность ]]>, (Так как вам все равно всегда приходится убегать, в большинстве случаев это делает разделы CDATA бесполезными.)

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

Вы пытались поместить свои данные в раздел CDATA? это должно помешать парсеру попытаться прочитать содержимое тега.

http://en.wikipedia.org/wiki/CDATA

Другие вопросы по тегам