2011-08-04 18 views
3

ソケットを介してサードパーティから送信された(複数の)xmlドキュメントの連続ストリームを解析する際に問題があります。ソケットを介して送信されるXMLストリームのサンプルは次のとおりです。PythonのソケットストリームからXMLドキュメントを構築/解析する

import socket 
import xml.etree.cElementTree as etree 
from StringIO import StringIO 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
host = "IP.IP.IP.IP" 
port = "8080" 
addr = (host,port) 
s.connect(addr) 

def iparse(packet): 
    for _, element in etree.iterparse(packet): 
     print ("%s, %s" %(element.tag, element.text)) 
     element.clear() 
    #if complete <event> node received, publish node 

data = "<feeds>" 
while 1: 
    chunk = s.recv(1024) 
    #replace the xml doc declarations as comments 
    data += (chunk.replace("<?","<!--")).replace("?>","-->") 
    iparse(StringIO(data)) 

物事が通過iparse反復処理するには、しかし... forループをうまく動作:

<?xml version="1.0"?><event><user id="1098"/><viewpage>109958</viewpage></event> 
<?xml version="1.0"?><event><user id="1482"/><actions><edit>102865</edit><commit>1592356</commit></actions></event> 
etc. 

ここで私が使用しているコードです毎回全文書iparseは、代わりにストリーム上に表示されるように、1つの整形式タグノード(イベント)を構築して反復することは可能ですか?整形されたパケットを読み取るためにチャンクサイズを設定できる方法はないことに注意してください。バッファを使用してパケットを構築し、パケットが整形されたらiparseに送信するだけですが、それは不要な遅延を招く可能性がありますか?これを処理するより良い方法はありますか?

EDIT:

各イベントは、別個であるが、ルート<event>下の任意のノードを含んでいます。 iparseは、リアルタイムアナリティクスグラフ作成システム内の任意の数のサブスクライバに最新のイベントを公開することが期待されています。

+0

希望の結果の例を教えてください。 –

+0

必要な出力をよりよく反映させるために編集しました。 – pynoob

+0

私はあなたを助けることはできないと思います。この時点で私の頭の上にはビットがあります –

答えて

0

feed parsinglxml.etreeに見ることができます。しかし、文書が絶え間なく成長しているので、問題にぶつかります。

XMLのBLOBは改行文字で区切られていますか?もしそうなら、あなたは新しい行を打ち、各行をxmlパーサーに送るまであなたがバッファリングすることをお勧めします。 Αla Twisted's LineReceiver

実際、私の場合は、おそらくTwistedにこのアプリケーションを書いています。一緒にネットワークサービスを結びつけることは、私のための一般的な使用事例です。

+0

しかし、あなたが指摘しているような解決策は、文書が成長し続けるにつれて問題を抱えています。私が持っているもう一つの問題は、フィードパーサが明示的に 'close()'コールを再利用する必要があることです。バッファを使い、 'iparse'(' iterparse'を使う代わりに 'xmltree.fromstring()'に書き直すことができます)に整形された文字列を投げ込むように見えます。 – pynoob