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 パーサーがエスケープ コードをバーフします。

これに対処する 1 つの方法は、最初にエスケープ コードを除外することです。しかし、エスケープ コードが維持され、結果のファイルが etree のような XML ツールで解析できる場合、このようなことを行うことが可能でしょうか?

4

3 に答える 3

2

あなたの問題は、制御コードが適切な UTF-8 ではないということではありません。それは単なる ASCIIESCであり、友人は CDATA セクション内であっても適切な XML 文字ではありません。

U+0020 より小さい値を持つ XML 1.0 の唯一の有効な XML 文字は、U+0009 (タブ)、U+000A (改行)、および U+000D (改行) です。エスケープ (U+001B) などの他のコードを含むものを記録したい場合は、何らかの方法でそれらをエスケープする必要があります。他に選択肢はありません。

于 2011-10-22T12:32:29.127 に答える
1

Charles が言ったように、ほとんどの制御コードは XML 1.0 ファイルにまったく含まれていない可能性があります。

ただし、XML 1.1 の要求に耐えられる場合は、そこで使用できます。生の文字として含めることはできませんが、文字参照として含めることはできます。例えば:

&#27;

CDATA セクションに文字参照を記述できないため (アンパサンド-ハッシュ-... として解釈されるだけです)、ラッパーを失い、文字をエンティティ参照に相当するものに<![CDATA[手動でエスケープする必要があります。&<>

とにかくこれを行う必要があることに注意してください: CDATA セクションは、テキストエスケープの責任を免除しません。これは、内部のテキストにシーケンスが含まれている場合に失敗するためです]]>。(とにかくエスケープを常に行う必要があるため、ほとんどの場合、CDATA セクションはほとんど役に立たなくなります。)

XML 1.1 は制御コードに関してより寛大ですが、すべてがそれをサポートしているわけではなく、NUL 文字 ( ) を含めることもできません&#0;。一般に、XML に制御文字を含めることはお勧めできません。アドホック エンコーディング スキームを使用して、バイナリを適合させることができます。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 に答える