【问题标题】:Storing VT100 escape codes in an XML file在 XML 文件中存储 VT100 转义码
【发布时间】:2011-10-22 12:05:23
【问题描述】:

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

解决此问题的一种方法是先发送至filter out the escape codes。但是,是否有可能在维护转义码并且生成的文件可以由 XML 工具(如 etree)解析的情况下做这样的事情?

【问题讨论】:

    标签: python xml unicode tty vt100


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      &#27;
      

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

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 是的,我确实尝试将我的数据放入 CDATA 部分,但这不起作用。我将编辑上面的示例代码以反映这一点。
        • 错误答案:解析器确实读取了 CDATA 部分的内容,并检查它是否只包含合法的 XML 字符(不包括 ESC 字符)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-15
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多