juliusからのxmlをpythonでパース
あいかわらずラズパイ3(jessie)の生みの苦しみは続きます。
洗礼ポイント③音声認識エンジンjuliusの導入
ダウンロード・インストールまでは問題なく進みましたが、サーバモードで起動し、wheezyのときに自作したクライアントを起動しましたがうまく動きません。もともと自作した理由がjuliusから返ってくるxmlをどうやってpythonでパースするかわからなかった、ということなのでこれを期に、正攻法(xmlのパース)に切り替えたいと思いました。
先哲のブログをググって今度はここにたどり着きました。以下がそのコードです。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import serial
import xml.etree.ElementTree as ET
host = 'localhost'
port = 10500
clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsock.connect((host, port))
com = serial.Serial('/dev/ttyAMA0', 57600, timeout=10)
while True:
recv_data = clientsock.recv(512)
# juliusの区切り文字で分割
sp = recv_data.split('.\n')
#print(sp)
for elem in sp:
if(elem != ''):
try:
root = ET.fromstring(elem)
for word in root.iter('WHYPO'):
command = word.get('WORD')
print(command)
com.write(command)
except:
print("Failed to parse")
ただ自分の環境で、上記を実行すると結構な頻度で"Failed to parse"が返ってきてしまいます。調べてみると、 juliusからの応答を区切り文字'.\n'で分割するとき、認識結果が入っている<SHYPO>タグが</SHYPO>で閉じられる手前で2つに分割されていることがわかりました。
そこで、以下のようにするとだいたい成功するようになりました。<SHYPOがあって</SHYPO>がない文が来たらパースせず次の文とつなげてからパースする、という安直なものです。
'.\n'で分割するところからです。(先哲はシリアル通信してcommandを送っているようですが、当面不要なのでその部分は削っています。)
sp = recv_data.split('.\n')
for elem in sp:
if(elem != ''):
if elem.find('<SHYPO') != -1 and elem.find('</SHYPO>') == -1:
elemBuffer = elem
else:
if elem.find('<SHYPO') == -1 and elem.find('</SHYPO>') != -1:
elem = elemBuffer + elem
elemBuffer = ''
try:
root = ET.fromstring(elem)
for word in root.iter('WHYPO'):
command = word.get('WORD')
print(command)
global_order = command
except:
pass
#print("Failed to parse")
洗礼ポイント③音声認識エンジンjuliusの導入
ダウンロード・インストールまでは問題なく進みましたが、サーバモードで起動し、wheezyのときに自作したクライアントを起動しましたがうまく動きません。もともと自作した理由がjuliusから返ってくるxmlをどうやってpythonでパースするかわからなかった、ということなのでこれを期に、正攻法(xmlのパース)に切り替えたいと思いました。
先哲のブログをググって今度はここにたどり着きました。以下がそのコードです。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import serial
import xml.etree.ElementTree as ET
host = 'localhost'
port = 10500
clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsock.connect((host, port))
com = serial.Serial('/dev/ttyAMA0', 57600, timeout=10)
while True:
recv_data = clientsock.recv(512)
# juliusの区切り文字で分割
sp = recv_data.split('.\n')
#print(sp)
for elem in sp:
if(elem != ''):
try:
root = ET.fromstring(elem)
for word in root.iter('WHYPO'):
command = word.get('WORD')
print(command)
com.write(command)
except:
print("Failed to parse")
ただ自分の環境で、上記を実行すると結構な頻度で"Failed to parse"が返ってきてしまいます。調べてみると、 juliusからの応答を区切り文字'.\n'で分割するとき、認識結果が入っている<SHYPO>タグが</SHYPO>で閉じられる手前で2つに分割されていることがわかりました。
そこで、以下のようにするとだいたい成功するようになりました。<SHYPOがあって</SHYPO>がない文が来たらパースせず次の文とつなげてからパースする、という安直なものです。
'.\n'で分割するところからです。(先哲はシリアル通信してcommandを送っているようですが、当面不要なのでその部分は削っています。)
sp = recv_data.split('.\n')
for elem in sp:
if(elem != ''):
if elem.find('<SHYPO') != -1 and elem.find('</SHYPO>') == -1:
elemBuffer = elem
else:
if elem.find('<SHYPO') == -1 and elem.find('</SHYPO>') != -1:
elem = elemBuffer + elem
elemBuffer = ''
try:
root = ET.fromstring(elem)
for word in root.iter('WHYPO'):
command = word.get('WORD')
print(command)
global_order = command
except:
pass
#print("Failed to parse")
コメント