1

TCP/IP 通信と XML を使用して、クライアント (アプリケーション) とサーバー (アイトラッカー) の間でデータを送信するアイトラッカーがあります。以下は、アイトラッカーがオンのときに連続して受け取る XML データ文字列の例です。私がやりたいことは、私が持っている別の関数への入力として、データ、FPOGX および FPOGY を使用できるようにすることです。問題は、それらが変数ではなく、単純にそれらを呼び出すことができないことです。このデータ ストリームを解析するにはどうすればよいですか? XML を扱うのはこれが初めてです。例をいただければ幸いです。ありがとう!

CLIENT SEND: <SET ID="ENABLE_SEND_COUNTER" STATE="1" />
SERVER SEND: <ACK ID="ENABLE_SEND_COUNTER" STATE="1" />
CLIENT SEND: <SET ID="ENABLE_SEND_POG_FIX" STATE="1" />
SERVER SEND: <ACK ID="ENABLE_SEND_POG_FIX" STATE="1" />
CLIENT SEND: <SET ID="ENABLE_SEND_DATA" STATE="1" />
SERVER SEND: <ACK ID="ENABLE_SEND_DATA" STATE="1" />
SERVER SEND: <REC CNT="72" FPOGX="0.5065" FPOGY="0.4390"
FPOGD="0.078" FPOGID="468" FPOGV="1"/>
SERVER SEND: <REC CNT="73" FPOGX="0.5071" FPOGY="0.4409"
FPOGD="0.094" FPOGID="468" FPOGV="1"/>
SERVER SEND: <REC CNT="74" FPOGX="0.5077" FPOGY="0.4428"
FPOGD="0.109" FPOGID="468" FPOGV="1"/>

コードの一部のスニペットを次に示します。

import xml.etree.cElementTree as ET
import cv2
import cv
import socket

# Code to grab different data from eye-tracker
'...'
# Code to create window and initialize camera
'...'
def xmlParse():
    rxdat = s.recv(1024)  # Syntax from eye-tracker to grab XML data stream of <REC />
    if(rxdat.find("ACK") == 1):  # First two XML have the <ACK /> tag but I don't need those
        pass
    else: # Here is the part where it parses and converts the data to float
        rxdat = '<data>' + rxdat + '</data>' 
        xml = ET.fromstring(rxdat)
        for element in xml:
            X = float(xml[0].attrib['FPOGX'])
            Y = float(xml[0].attrib['FPOGY'])
        return (X, Y)

# Def to average samples of incoming X and Y
'...'
# Def that uses xmlParse() and average() to return the averages of X and Y
'...'
# Def for mouse click events
'...'
# Some code that makes our window graphics
'...'
for i in range(0,2):    # Round-about way to get rid of the first two "NoneType"
    xmlParse()

while True:
    Img = cv.QueryFrame(capture) # capture defined earlier
    drawarrow(polyF, polyB, polyL, polyR) # Our window graphics definition
    cv.ShowImage("window", Img)
    (X, Y) = gazeCoordinates() # Def that uses xmlParse and average to return the averages of X and Y
    if cv.WaitKey(20) & 0xFF == 27:
        break

cv2.destroyAllWindows()

与えられたエラーはParseError: not well-formed (invalid token)xml = ET.fromstring(rxdat)コードの

定義 xmlParse() 自体と結果を出力するだけで機能します。しかし、ウィンドウ、グラフィックス、およびデータの使用を追加し始めると、そのエラーが発生し始めます。

4

1 に答える 1

2

上記のすべてのテキストを解析する必要はなく (すべてをまとめた場合、適切な xml ではありません)、一度に 1 つの xml 要素だけを解析する必要があると仮定すると、次のようなことを試すことをお勧めします。目的のキーと値のペアを含む属性のディクショナリが作成されます。

>>> import xml.etree.cElementTree as ET
>>> xml_string = '<REC CNT="72" FPOGX="0.5065" FPOGY="0.4390" FPOGD="0.078" FPOGID="468" FPOGV="1"/>'
>>> xml = ET.fromstring(xml_string)
>>> xml.attrib  # a dict
{'CNT': '72', 'FPOGV': '1', 'FPOGY': '0.4390', 'FPOGX': '0.5065', 'FPOGD': '0.078', 'FPOGID': '468'}
>>> xml.attrib['FPOGX'], xml.attrib['FPOGY']
('0.5065', '0.4390')

ここで xml.etree.ElementTree のドキュメントを確認できます。

編集

コメントに関しては、xml のjunk後 (または前) に含まれる可能性のあるものをコード化するために、解析する前に文字列を xml 要素でラップすることを試みることができます。たとえば、これを試すことができます (最初の xml 文字列の末尾に追加した「ジャンク」に注意してください)。

>>> xml_string = '<REC CNT="72" FPOGX="0.5065" FPOGY="0.4390" FPOGD="0.078" FPOGID="468" FPOGV="1"/>here is some junk that should not be here and that does not fit into xml.'
>>> xml_string = '<data>' + xml_string + '</data>'  # makes sure that the xml has an outer tag
>>> xml = ET.fromstring(xml_string)
>>> for element in xml:  # now need to iterate through <data> tag
    print element.attrib  # a dict
    {'CNT': '72', 'FPOGV': '1', 'FPOGY': '0.4390', 'FPOGX': '0.5065', 'FPOGD': '0.078', 'FPOGID': '468'}
>>> xml[0].attrib['FPOGX'], xml[0].attrib['FPOGY']  # or you can find attributes by indices (like a list)
    ('0.5065', '0.4390')

編集2

あなたのPythonは問題ないようです。問題は、xml 文字列で受信している文字 (または複数の文字) にあります。(<data></data>要素も問題ありません。)これを置き換えることで、どのトークンが問題を引き起こしているかを把握できます。

xml = ET.fromstring(rxdat)

これとともに:

try:
    xml = ET.fromstring(rxdat)
except:
    print rxdat  # will print the string or strings it cannot parse

このテストの結果によっては、文字または文字グループをエスケープする必要がある場合があります。

于 2014-01-16T03:28:55.100 に答える