0

我正在编写一个记录终端交互的 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 解析器在转义码上出错。

解决这个问题的一种方法是首先过滤掉转义码。但是,是否可以在维护转义码的情况下执行类似的操作,并且可以通过 etree 等 XML 工具解析生成的文件?

4

3 回答 3

2

您的问题不在于控制代码不是正确的 UTF-8,它们只是 ASCIIESC并且朋友不是正确的 XML 字符,即使在 CDATA 部分中也是如此。

在 XML 1.0 中,值小于 U+0020 的唯一有效 XML 字符是 U+0009(制表符)、U+000A(换行符)和 U+000D(回车符)。如果您想记录涉及其他代码(例如转义(U+001B))的内容,则必须以某种方式对其进行转义。没有其他选择。

于 2011-10-22T12:32:29.127 回答
1

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

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

&#27;

因为您不能在 CDATA 部分中编写字符引用(它们只会被解释为与符号哈希-...),所以您将不得不丢失<![CDATA[包装器并手动&<>将字符转义为它们的实体引用等效项。

请注意,无论如何您都应该这样做:CDATA 部分不会免除您对文本转义的责任,因为如果其中的文本包含 sequence ,它们将失败]]>。(因为无论如何你总是必须做一些转义,这使得 CDATA 部分大部分时间都毫无用处。)

XML 1.1 对控制代码更为宽松,但并非所有内容都支持它,并且您仍然不能包含 NUL 字符 ( &#0;)。一般来说,在 XML 中包含控制字符并不是一个好主意。您可以使用 ad-hoc 编码方案来适应二进制文件;base-64 很流行,但不是很可读。替代方案可能包括使用私人使用区域中的随机字符作为替代,如果只有您自己的应用程序将处理文件,或者将它们编码为元素(例如<esc color="1"/>)。

于 2011-10-23T15:23:28.853 回答
-1

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

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

于 2011-10-22T12:09:26.920 回答