python - 在 Python 中解析 XML 字符串片段流

标签 python xml string data-stream

我有一个眼动仪,使用 TCP/IP 通信和 XML 在客户端(应用程序)和服务器(眼动仪)之间发送数据。以下是我在眼动仪打开时连续接收的 XML 数据字符串的示例。我想做的是能够使用数据 FPOGX 和 FOGY 作为我拥有的另一个函数的输入。问题是它们不是变量,您不能简单地调用它们。我如何解析这个数据流?这是我第一次使用 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() 本身并打印出结果就可以了。但是,一旦我开始添加窗口、图形并使用数据,它就会开始发出该错误。

最佳答案

假设您不需要解析上面的所有文本(当全部放在一起时,这不是正确的 xml),而是一次只解析一个 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 here 的文档.

编辑

关于您的评论,您可以尝试在解析字符串之前将字符串包装在 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> 元素也很好。)您可以通过替换以下内容来找出哪个 token 给您带来麻烦:

xml = ET.fromstring(rxdat)

这样:

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

您可能需要转义一个字符或一组字符,具体取决于您从此测试中发现的内容。

关于python - 在 Python 中解析 XML 字符串片段流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21152681/

相关文章:

python - 防止 ansible 使用 sudo

python - 为什么我的 .fetchone 函数返回 "none"?

python - 值错误 : zero length field name in format with read and write

java - Java 中的 W3C dom api

python - 如何做更多定制化的zeppelin notebook?

xml - <beans :beans> and <beans>之间的区别

python - 如何使用 lxml 创建文本节点?

c++ - 以相反的顺序打印输入的字符串单词

javascript - 使用字符串数组替换字符串中的匹配项

java Swing : Is it possible change color of a specific string variable?