CmdLoadFromFile - XML Grammatik laden Problem

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Buell
User
Beiträge: 90
Registriert: Samstag 29. Oktober 2005, 14:17

Hallo Leutz,

bin am verzweifeln...

ich bastel ein bißchen mit Sapi5.1 herum (Microsoft Speech SDK). Läuft ja soweit auch alles wunderbar im Dictation Mode und das Laden einer Liste von Wörtern zum Command + Control geht auch ganz anständig. Um mit meiner Entwicklung jedoch weiter zu kommen ist es notwendig komplexe Grammatiken zu laden, also aus xml Dateien. Da es für Python keine wirklichen Beispiele dafür gibt habe ich mir mal VB als Referenz hergenommen. Dort gibt es die Funktion CmdLoadFromFile() die es in Python auch gibt. Leider bin ich anscheinend zu blöd...

VB Code Beispiel:

Code: Alles auswählen

Option Explicit

Dim C As SpeechLib.SpSharedRecoContext
Dim G1 As SpeechLib.ISpeechRecoGrammar
Dim G2 As SpeechLib.ISpeechRecoGrammar

Private Sub Command1_Click()
    Dim GT As Variant               'Temp grammar in Variant variable

    On Error GoTo EH

    GT = GrammarToMemory(G1)         'GT is temp version of grammar G
    Call G2.CmdLoadFromMemory(GT, SLOStatic)

EH:
    If Err.Number Then ShowErrMsg
End Sub

Private Sub Form_Load()
    On Error GoTo EH

    Set C = New SpSharedRecoContext
    Set G1 = C.CreateGrammar
    Set G2 = C.CreateGrammar

    Call G1.CmdLoadFromFile("c:\sol.xml", SLODynamic)

EH:
    If Err.Number Then ShowErrMsg
End Sub

Private Function GrammarToMemory(objGRM As SpeechLib.ISpeechRecoGrammar) As Variant
    On Error GoTo EH

    'Make changes to a standard grammar, and save it as temp grammar.
    'Add rules to grammar, delete rules from grammar, or other changes here.

    'Return the variant from ISpeechGrammarRules.CommitAndSave
    GrammarToMemory = objGRM.Rules.CommitAndSave("")

EH:
    If Err.Number Then ShowErrMsg
End Sub

Private Sub ShowErrMsg()

    ' Declare identifiers:
    Const NL = vbNewLine
    Dim T As String

    T = "Desc: " & Err.Description & NL
    T = T & "Err #: " & Err.Number
    MsgBox T, vbExclamation, "Run-Time Error"
    End

End Sub
Bei mir in Python sieht das dann so aus:

Code: Alles auswählen

...
self.listener = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
self.context = self.listener.CreateRecoContext()
self.grammar = self.context.CreateGrammar(0)
self.grammar.CmdLoadFromFile("sol.xml", constants.SLODynamic)
self.grammar.CmdSetRuleIdState(0, constants.SGDSActive)
...
Funtkioniert aber irgendwie nicht. Das CmdLoadFromFile wird zwar ausgeführt, aber mit Fehlermeldung

Code: Alles auswählen

File "D:\Business Informatics\HiWi\MDI_SpeechTool_with_COM_SERVER\SR\SAPI5\TestFileImport.py", line 104, in __init__
    self.grammar.CmdLoadFromFile(str("sol.xml"), constants.SLODynamic)
  File "C:\Programme\Python24\lib\site-packages\win32com\gen_py\C866CA3A-32F7-11D2-9602-00C04F8EE628x0x5x0.py", line 2315, in CmdLoadFromFile
    , LoadOption)
com_error: (-2147352567, 'Ausnahmefehler aufgetreten.', (0, None, None, None, 0, -2147200942), None)
zurückgewiesen. Egal wo die xml Datei gespeichert ist und welchen Pfad man angibt, sie wird nicht geöffnet!

Hatte mir jetzt schon aus lauter Not heraus überlegt die xml Datei zu parsen und alles einzeln in die Grammatik zu laden, aber das wäre ein Riesen Aufwand.

Ach so, hier noch die Beispiel-Grammatik (sol.xml):

Code: Alles auswählen

<GRAMMAR LANGID="409">
    <DEFINE>
        <ID NAME="FROM" VAL="1"/>
        <ID NAME="TO" VAL="2"/>
        <ID NAME="SUIT" VAL="3"/>
        <ID NAME="COLOR" VAL="4"/>
        <ID NAME="RANK" VAL="5"/>
        <ID NAME="ColorRed" VAL="11101"/>
        <ID NAME="ColorBlack" VAL="10011"/>
	<ID NAME="RID_NewGame" VAL="101"/>
	<ID NAME="RID_MoveCard" VAL="102"/>
	<ID NAME="RID_Rank" VAL="103"/>
    </DEFINE>
   <RULE NAME="newgame" ID="RID_NewGame" TOPLEVEL="ACTIVE">
      <P>new +game</P><O>-please</O>
   </RULE>
   <RULE NAME="playcard" TOPLEVEL="ACTIVE" EXPORT="1">
      <O>please</O>
      <P>play the</P>
      <RULEREF NAME="card"/>
      <O>please</O>
   </RULE>
   <RULE NAME="movecard" ID="RID_MoveCard" TOPLEVEL="ACTIVE">
      <O>please</O>
      <P>
         <L>
            <P>move</P>
            <P>put</P>
         </L>
         <P>the</P>
      </P>
      <RULEREF PROPNAME="from" PROPID="FROM" NAME="card"/>
      <O>
         <L>
            <P>on</P>
            <P>to</P>
         </L>
         <P>the</P>
         <RULEREF PROPNAME="to" PROPID="TO" NAME="card"/>
      </O>
      <O>please</O>
   </RULE>
   <RULE NAME="card">
      <L>
         <P>
            <L PROPNAME="color" PROPID="COLOR">
               <P VAL="ColorRed">red</P>
               <P VAL="ColorBlack">black</P>
            </L>
            <RULEREF NAME="rank"/>
         </P>
         <P>
            <RULEREF NAME="rank"/>
            <O>
               <P>of</P>
               <L PROPNAME="suit" PROPID="SUIT">
                  <P VAL="0">clubs</P>
                  <P VAL="1">hearts</P>
                  <P VAL="2">diamonds</P>
                  <P VAL="3">spades</P>
               </L>
            </O>
         </P>
         <L PROPNAME="suit" PROPID="SUIT">
            <P VAL="0">club</P>
            <P VAL="1">heart</P>
            <P VAL="2">diamond</P>
            <P VAL="3">spade</P>
         </L>
      </L>
   </RULE>
   <RULE NAME="rank" ID="RID_Rank">
      <L PROPNAME="rank" PROPID="RANK">
         <P VAL="1">ace</P>
         <P VAL="2">two</P>
         <P VAL="3">three</P>
         <P VAL="4">four</P>
         <P VAL="5">five</P>
         <P VAL="6">six</P>
         <P VAL="7">seven</P>
         <P VAL="8">eight</P>
         <P VAL="9">nine</P>
         <P VAL="10">ten</P>
         <P VAL="11">jack</P>
         <P VAL="12">queen</P>
         <P VAL="13">king</P>
         <P VAL="12">lady</P>
         <P VAL="13">emperor</P>
      </L>
   </RULE>
</GRAMMAR>
Wäre für jede Hilfe Dankbar!
Buell
User
Beiträge: 90
Registriert: Samstag 29. Oktober 2005, 14:17

endlich den Fehler gefunden:

nicht:

Code: Alles auswählen

self.grammar.CmdLoadFromFile(filepath, constants.SLODynamic)
sondern:

Code: Alles auswählen

load_grammar = self.grammar.CmdLoadFromFile(filepath, constants.SLODynamic)

... ohne worte ...
Antworten