将VT100转义码存储在XML文件中

时间:2011-10-22 12:05:24

标签: python xml unicode tty vt100

我正在编写一个记录终端交互的Python程序(类似于脚本程序),我想以XML格式存储日志。

问题是终端交互包括VT100转义码。如果我将数据写入UTF-8编码的文件,Python就不会抱怨,例如:

...
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,这会导致像etree这样的XML解析器对转义码进行barf。

解决这个问题的一种方法是首先filter out the escape codes。但是,如果可以做这样的事情,其中​​维护转义码并且结果文件可以由像etree这样的XML工具解析?

3 个答案:

答案 0 :(得分:2)

你的问题不在于控制代码不是正确的UTF-8,它们只是ASCII ESC而朋友不是正确的XML字符,即使在CDATA部分内也是如此。

XML 1.0中唯一有效值小于U + 0020的XML字符是U + 0009(制表符),U + 000A(换行符)和U + 000D(回车)。如果你想记录涉及其他代码的东西,比如escape(U + 001B)那么你将不得不以某种方式逃避它们。没有其他选择。

答案 1 :(得分:1)

正如Charles所说,大多数控制代码可能根本不包含在XML 1.0文件中。

但是,如果您可以使用XML 1.1,则可以在那里使用它们。它们不能作为原始字符包含在内,但可以作为字符引用。例如:

&#27;

因为您无法在CDATA部分中编写字符引用(它们只是被解释为ampersand-hash -...),您将不得不丢失<![CDATA[包装并手动转义{{1字符到它们的实体引用等价物。

请注意,无论如何都应该这样做:CDATA部分不会免除您对文本转义的责任,因为如果内部文本包含序列&<>,它们将失败。 (因为你总是必须进行一些转义,这使得CDATA部分在大多数情况下都没用。)

XML 1.1对控制代码更加宽容,但并非所有内容都支持它,您仍然不能包含NUL字符(]]>)。通常,在XML中包含控制字符并不是一个好主意。您可以使用ad-hoc编码方案来适应二进制; base-64很受欢迎,但不是很容易阅读。替代方案可能包括使用私有使用区中的随机字符作为替代,如果它只是您自己的应用程序将处理文件,或将它们编码为元素(例如&#0;)。

答案 2 :(得分:-1)

您是否尝试将数据放入CDATA部分?这应该可以防止解析器尝试读取标记的内容。

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