How do I access recognition result rules and phrase properties?

Last reviewed: 7/15/2011

HOW Article ID: H071129

The information in this article applies to:

  • SpeechKit 7

Summary

SpeechKit 7 provides support for enumerating SAPI grammar rule and phrase properties on recognition results.

More Information

For most applications, processing the spoken result on grammar recognition events is adequate.

For more complicated grammar and processing scenarios however, it may be desirable to process the rule and phrase properties within the recognition results.

SpeechKit 7 provides 2 new speech resources: CSRPhraseProperty and CSRRule that can be enumerated on recognition events.

The following example illustrates enumerating phrase properties.


private void NChantSR1_HasEvent(object sender, SpeechKit.HasEventArgs e)
{
    // Get the number of events
    int numberOfEvents = NChantSR1.GetResourceCount(ChantSpeechResource.CSREvent,0,0);
    for (int i = 0; i < numberOfEvents; i++)
    {
        // Get the event from the event queue
        NChantSREvent nChantSREvent = NChantSR1.GetChantSREvent(0);

        // Process the type of callback event
        switch (nChantSREvent.ChantCallback)
        {
            case (int)ChantCallback.CCSRHasPhrase :
                // Get the number of phrase properties
                int numberOfPhraseProperties = nChantSREvent.GetResourceCount(ChantSpeechResource.CSRPhraseProperty);
                for (int j = 0; j < numberOfPhraseProperties; j++)
                {
                    NChantPhraseProperty nChantPhraseProperty = nChantSREvent.GetChantPhraseProperty(j);
                    // Phrase properties are a tree structure
                    ProcessPhraseProperty(nChantPhraseProperty);                   
                }
                break;
            default :
                break;
        }
        // Remove the event from the event queue
        NChantSR1.RemoveResource(ChantSpeechResource.CSREvent, 0, "");
    }
}
private void ProcessPhraseProperty(NChantPhraseProperty nChantPhraseProperty)
{
    // Get the number of phrase properties
    int numberOfPhraseProperties = nChantPhraseProperty.GetResourceCount(ChantSpeechResource.CSRPhraseProperty);
    for (int j = 0; j < numberOfPhraseProperties; j++)
    {
        NChantPhraseProperty nChildChantPhraseProperty = nChantPhraseProperty.GetChantPhraseProperty(j);
        // Phrase properties are a tree structure
        ProcessPhraseProperty(nChildChantPhraseProperty);                   
    }
    // Process property values
    int id = nChantPhraseProperty.ID;
    string name = nChantPhraseProperty.Name;
}

LRESULT CRecognitionDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class
    if (message == m_HasEvent)
    {
        // Get the number of events
        int numberOfEvents = pCChantSR->GetResourceCount(CSREvent);
        for (int i = 0; i < numberOfEvents; i++)
        {
            // Get the event from the event queue
            CChantSREvent* pChantSREvent = pCChantSR->GetChantSREvent(0);
            // Process the type of callback event
            switch (pChantSREvent->GetChantCallback())
            {
                case CCSRHasPhrase :
                {
                    int numberOfPhraseProperties = pChantSREvent->GetResourceCount(CSRPhraseProperty);
                    for (int j = 0; j < numberOfPhraseProperties; j++)
                    {
                        CChantPhraseProperty* pChantPhraseProperty = pChantSREvent->GetChantPhraseProperty(j);
                        // Phrase properties are a tree structure
                        ProcessPhraseProperty(pChantPhraseProperty);
                    }
                    break;
                }
                default :
                    break;
            }
            // Remove the event from the event queue
            pCChantSR->RemoveResource(CSREvent, 0);
            delete pChantSREvent;
        }
    }
}
void CRecognitionDlg::ProcessPhraseProperty(CChantPhraseProperty* pChantPhraseProperty) 
{
    int numberOfPhraseProperties = pChantPhraseProperty->GetResourceCount(CSRPhraseProperty);
    for (int j = 0; j < numberOfPhraseProperties; j++)
    {
        CChantPhraseProperty* pChildChantPhraseProperty = pChantPhraseProperty->GetChantPhraseProperty(j);
        // Phrase properties are a tree structure
        ProcessPhraseProperty(pChildChantPhraseProperty);
    }
    // Process property values
    int id = pChantPhraseProperty->GetID();
    wchar_t* pszName = pChantPhraseProperty->GetName();
}
    

void __fastcall TForm1::OnHasEvent(TMessage& msg)
{
    int numberOfEvents = ChantSR1->GetResourceCount(CSREvent,0,0);
    for (int i = 0; i < numberOfEvents; i++)
    {
        // Get the event from the event queue
        CChantSREvent* pEvent = ChantSR1->GetChantSREvent(0);
        switch (pEvent->GetChantCallback())
        {
            default:
                break;
            case CCSRHasPhrase:
            {
                int numberOfPhraseProperties = pChantSREvent->GetResourceCount(CSRPhraseProperty);
                for (int j = 0; j < numberOfPhraseProperties; j++)
                {
                    CChantPhraseProperty* pChantPhraseProperty = pChantSREvent->GetChantPhraseProperty(j);
                    // Phrase properties are a tree structure
                    ProcessPhraseProperty(pChantPhraseProperty);
                }
                break;
            }
        }
        // Remove the event from the event queue
        ChantSR1->RemoveResource(CSREvent,0,"");
        delete pEvent;
    }
}
void __fastcall TForm1::ProcessPhraseProperty(CChantPhraseProperty* pChantPhraseProperty)
{
    int numberOfPhraseProperties = pChantPhraseProperty->GetResourceCount(CSRPhraseProperty);
    for (int j = 0; j < numberOfPhraseProperties; j++)
    {
        CChantPhraseProperty* pChildChantPhraseProperty = pChantPhraseProperty->GetChantPhraseProperty(j);
        // Phrase properties are a tree structure
        ProcessPhraseProperty(pChildChantPhraseProperty);
    }
    // Process property values
    int id = pChantPhraseProperty->GetID();
    String sName = pChantPhraseProperty->GetName();
}

procedure TForm1.OnHasEvent(var msg: TMessage);
var
tEvent: TChantSREvent;
numberOfEvents: Integer;
numberOfPhraseProperties: Integer;
i: Integer;
j: Integer;
aTChantPhraseProperty: TChantPhraseProperty; 
begin
    numberOfEvents := ChantSR1.GetResourceCount(CSREvent,0,0);
    for i := 0 to numberOfEvents - 1 do
    begin
        // Get the event from the event queue
        tEvent := ChantSR1.GetChantSREvent(0);
        case tEvent.ChantCallback of
        CCSRHasPhrase:
        begin
            numberOfPhraseProperties := tEvent.GetResourceCount(CSRPhraseProperty);
            for j := 0 to numberOfPhraseProperties - 1 do
            begin
                aChildTChantPhraseProperty := tEvent.GetChantPhraseProperty(j);
                // Phrase properties are a tree structure
                ProcessPhraseProperty(aChildTChantPhraseProperty);
            end;
        end;
        end;
        // Remove the event from the event queue
        ChantSR1.RemoveResource(CSREvent, 0);
        tEvent.Destroy();
    end;
end;
procedure TForm1.ProcessPhraseProperty(TChantPhraseProperty aTChantPhraseProperty)
var
numberOfPhraseProperties: Integer;
aChildTChantPhraseProperty: TChantPhraseProperty;
j: Integer;
id: Integer;
name: string;
begin
    numberOfPhraseProperties := aTChantPhraseProperty.GetResourceCount(CSRPhraseProperty);
    for j := 0 to numberOfPhraseProperties - 1 do
    begin
        aChildTChantPhraseProperty := aTChantPhraseProperty.GetChantPhraseProperty(j);
        // Phrase properties are a tree structure
        ProcessPhraseProperty(aChildTChantPhraseProperty);
    end;
    // Process property values
    id := aTChantPhraseProperty.ID;
sName := aTChantPhraseProperty.Name;
end;
    

    
public void hasEvent(Object obj1, Object obj2) { // Get the number of events int numberOfEvents = JChantSR1.getResourceCount(ChantSpeechResource.CSREvent,0,0); for (int i = 0; i < numberOfEvents; i++) { // Get the event from the event queue JChantSREvent jChantSREvent = JChantSR1.getChantSREvent(0); // Process the type of callback event switch (jChantSREvent.getChantCallback()) { case ChantCallback.CCSRHasPhrase : { int numberOfPhraseProperties = jChantSREvent.getResourceCount(ChantSpeechResource.CSRPhraseProperty); for (int j = 0; j < numberOfPhraseProperties; j++) { JChantPhraseProperty jChantPhraseProperty = jChantSREvent.getChantPhraseProperty(j); // Phrase properties are a tree structure processPhraseProperty(jChantPhraseProperty); } } default : break; } // Remove the event from the event queue JChantSR1.removeResource(ChantSpeechResource.CSREvent, 0, ""); } } public void processPhraseProperty(JChantPhraseProperty jChantPhraseProperty) { int numberOfPhraseProperties = jChantPhraseProperty.getResourceCount(ChantSpeechResource.CSRPhraseProperty); for (int j = 0; j < numberOfPhraseProperties; j++) { JChantPhraseProperty jChildChantPhraseProperty = jChantPhraseProperty.getChantPhraseProperty(j); // Phrase properties are a tree structure processPhraseProperty(jChildChantPhraseProperty); } // Process property values int id = jChantPhraseProperty.getID(); String name = jChantPhraseProperty.getName(); }

<script language="javascript" for="WChantSR1" event="HasEvent"><!--
var wChantSREvent
var wChantPhraseProperty
// Get the number of events
var numberOfEvents = WChantSR1.GetResourceCount(CSREvent);
for (i = 0; i < numberOfEvents; i++)
{
    // Get the event from the event queue
    wChantSREvent = WChantSR1.GetResource(CSREvent, 0);
    // Process the type of callback event
    switch (wChantSREvent.ChantCallback)
    {
        default :
            break;
        case CCSRHasPhrase :
            var numberOfPhraseProperties = wChantSREvent.GetResourceCount(CSRPhraseProperty);
            for (j = 0; j < numberOfPhraseProperties; j++)
            {
                wChantPhraseProperty = wChantSREvent.GetResource(CSRPhraseProperty,j);
                // Phrase properties are a tree structure
                ProcessPhraseProperty(wChantPhraseProperty);
            }
        break;
    }
    // Remove the event from the event queue
    WChantSR1.RemoveResource(CSREvent, 0);
}
function ProcessPhraseProperty(WChantPhraseProperty wChantPhraseProperty)
{
    var numberOfPhraseProperties = wChantPhraseProperty.GetResourceCount(CSRPhraseProperty);
    for (j = 0; j < numberOfPhraseProperties; j++)
    {
        var wChildChantPhraseProperty = wChantPhraseProperty.GetResource(CSRPhraseProperty,j);
        // Phrase properties are a tree structure
        ProcessPhraseProperty(wChildChantPhraseProperty);
    }
    // Process property values
    var id = wChantPhraseProperty.ID;
    var name = wChantPhraseProperty.Name;
}
//-->
    

Private Sub XChantSR1_HasEvent()
Dim aXChantSREvent As XChantSREvent
Dim aXChantPhraseProperty As XChantPhraseProperty
Dim numberOfPhraseProperties As Long
Dim I As Integer
Dim J As Integer
' Get the number of events
numberOfPhraseProperties = XChantSR1.GetResourceCount(CSREvent)
For I = 0 To numberOfPhraseProperties - 1
' Get the event from the event queue
Set aXChantSREvent = XChantSR1.GetResource(CSREvent, 0)
' Process the type of callback event
Select Case aXChantSREvent.ChantCallback
    Case CCSRHasPhrase
        numberOfPhraseProperties = aXChantSREvent.GetResourceCount(CSRPhraseProperty)
        For J = 0 To numberOfPhraseProperties - 1
            Set aXChantPhraseProperty = aXChantSREvent.GetResource(CSRPhraseProperty, J)
            ' Phrase properties are a tree structure
            ProcessPhraseProperty aXChantPhraseProperty
        Next
    Case Else
End Select
' Remove the event from the event queue
XChantSR1.RemoveResource CSREvent, 0
Next
End Sub
Private Sub ProcessPhraseProperty(ByVal aXChantPhraseProperty As XChantPhraseProperty)
Dim aXChildChantPhraseProperty As XChantPhraseProperty
Dim numberOfPhraseProperties As Long
Dim J As Integer
Dim id as Integer
Dim name As String
numberOfPhraseProperties = aXChantPhraseProperty.GetResourceCount(CSRPhraseProperty)
For J = 0 To numberOfPhraseProperties - 1
    Set aXChildChantPhraseProperty = aXChantPhraseProperty.GetResource(CSRPhraseProperty, J)
    ' Phrase properties are a tree structure
    ProcessPhraseProperty aXChildChantPhraseProperty
Next
' Process property values
id = aXChantPhraseProperty.ID
name = aXChantPhraseProperty.Name
End Sub
        

Private Sub NChantSR1_HasEvent(ByVal sender As System.Object, ByVal e As SpeechKit.HasEventArgs) Handles NChantSR1.HasEvent
Dim nChantSREvent As NChantSREvent
Dim nChantPhraseProperty As NChantPhraseProperty
Dim numberOfEvents As Integer
Dim numberOfPhraseProperties As Integer
Dim I As Integer
Dim J As Integer
' Get the number of events
numberOfEvents = NChantSR1.GetResourceCount(ChantSpeechResource.CSREvent, 0, 0)
For I = 0 To numberOfEvents - 1
    ' Get the event from the event queue
    nChantSREvent = NChantSR1.GetChantSREvent(0)
    ' Process the type of callback event
    Select Case nChantSREvent.ChantCallback
        Case ChantCallback.CCSRHasPhrase
            numberOfPhraseProperties = nChantSREvent.GetResourceCount(ChantSpeechResource.CSRPhraseProperty)
            For J = 0 To numberOfPhraseProperties - 1
                nChantPhraseProperty = nChantSREvent.GetChantPhraseProperty(J)
                ' Phrase properties are a tree structure
                ProcessPhraseProperty(nChantPhraseProperty)
                Next
            Next
        Case Else
    End Select
    ' Remove the event from the event queue
    NChantSR1.RemoveResource(ChantSpeechResource.CSREvent, 0, "")
Next
End Sub
Private Sub ProcessPhraseProperty(ByVal nChantPhraseProperty As NChantPhraseProperty)
Dim nChildChantPhraseProperty As NChantPhraseProperty
Dim numberOfPhraseProperties As Long
Dim J As Integer
Dim id as Integer
Dim name As String
numberOfPhraseProperties = nChantPhraseProperty.GetResourceCount(CSRPhraseProperty)
For J = 0 To numberOfPhraseProperties - 1
    nChildChantPhraseProperty = nChantPhraseProperty.GetChantPhraseProperty(J)
    ' Phrase properties are a tree structure
    ProcessPhraseProperty(nChildChantPhraseProperty)
Next
' Process property values
id = nChantPhraseProperty.ID
name = nChantPhraseProperty.Name
End Sub

The following example illustrates enumerating rules.


private void NChantSR1_HasEvent(object sender, SpeechKit.HasEventArgs e)
{
    // Get the number of events
    int numberOfEvents = NChantSR1.GetResourceCount(ChantSpeechResource.CSREvent,0,0);
    for (int i = 0; i < numberOfEvents; i++)
    {
        // Get the event from the event queue
        NChantSREvent nChantSREvent = NChantSR1.GetChantSREvent(0);

        // Process the type of callback event
        switch (nChantSREvent.ChantCallback)
        {
            case (int)ChantCallback.CCSRHasPhrase :
                // Get the number of phrase properties
                int numberOfRules = nChantSREvent.GetResourceCount(ChantSpeechResource.CSRRule);
                for (int j = 0; j < numberOfRules; j++)
                {
                    NChantRule nChantRule = nChantSREvent.GetChantRule(j);
                    // Rules are a tree structure
                    ProcessRule(nChantRule);                   
                }
                break;
            default :
                break;
        }
        // Remove the event from the event queue
        NChantSR1.RemoveResource(ChantSpeechResource.CSREvent, 0, "");
    }
}
private void ProcessRule(NChantRule nChantRule)
{
    // Get the number of phrase properties
    int numberOfRules = nChantRule.GetResourceCount(ChantSpeechResource.CSRRule);
    for (int j = 0; j < numberOfRules; j++)
    {
        NChantRule nChildChantRule = nChantRule.GetChantRule(j);
        // Rules are a tree structure
        ProcessRule(nChildChantRule);                   
    }
    // Process property values
    int id = nChantRule.ID;
    string name = nChantRule.Name;
}

LRESULT CRecognitionDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class
    if (message == m_HasEvent)
    {
        // Get the number of events
        int numberOfEvents = pCChantSR->GetResourceCount(CSREvent);
        for (int i = 0; i < numberOfEvents; i++)
        {
            // Get the event from the event queue
            CChantSREvent* pChantSREvent = pCChantSR->GetChantSREvent(0);
            // Process the type of callback event
            switch (pChantSREvent->GetChantCallback())
            {
                case CCSRHasPhrase :
                {
                    int numberOfRules = pChantSREvent->GetResourceCount(CSRRule);
                    for (int j = 0; j < numberOfRules; j++)
                    {
                        CChantRule* pChantRule = pChantSREvent->GetChantRule(j);
                        // Rules are a tree structure
                        ProcessRule(pChantRule);
                    }
                    break;
                }
                default :
                    break;
            }
            // Remove the event from the event queue
            pCChantSR->RemoveResource(CSREvent, 0);
            delete pChantSREvent;
        }
    }
}
void CRecognitionDlg::ProcessRule(CChantRule* pChantRule) 
{
    int numberOfRules = pChantRule->GetResourceCount(CSRRule);
    for (int j = 0; j < numberOfRules; j++)
    {
        CChantRule* pChildChantRule = pChantRule->GetChantRule(j);
        // Rules are a tree structure
        ProcessRule(pChildChantRule);
    }
    // Process property values
    int id = pChantRule->GetID();
    wchar_t* pszName = pChantRule->GetName();
}
    

void __fastcall TForm1::OnHasEvent(TMessage& msg)
{
    int numberOfEvents = ChantSR1->GetResourceCount(CSREvent,0,0);
    for (int i = 0; i < numberOfEvents; i++)
    {
        // Get the event from the event queue
        CChantSREvent* pEvent = ChantSR1->GetChantSREvent(0);
        switch (pEvent->GetChantCallback())
        {
            default:
                break;
            case CCSRHasPhrase:
            {
                int numberOfRules = pChantSREvent->GetResourceCount(CSRRule);
                for (int j = 0; j < numberOfRules; j++)
                {
                    CChantRule* pChantRule = pChantSREvent->GetChantRule(j);
                    // Rules are a tree structure
                    ProcessRule(pChantRule);
                }
                break;
            }
        }
        // Remove the event from the event queue
        ChantSR1->RemoveResource(CSREvent,0,"");
        delete pEvent;
    }
}
void __fastcall TForm1::ProcessRule(CChantRule* pChantRule)
{
    int numberOfRules = pChantRule->GetResourceCount(CSRRule);
    for (int j = 0; j < numberOfRules; j++)
    {
        CChantRule* pChildChantRule = pChantRule->GetChantRule(j);
        // Rules are a tree structure
        ProcessRule(pChildChantRule);
    }
    // Process property values
    int id = pChantRule->GetID();
    String sName = pChantRule->GetName();
}

procedure TForm1.OnHasEvent(var msg: TMessage);
var
tEvent: TChantSREvent;
numberOfEvents: Integer;
numberOfRules: Integer;
i: Integer;
j: Integer;
aTChantRule: TChantRule; 
begin
    numberOfEvents := ChantSR1.GetResourceCount(CSREvent,0,0);
    for i := 0 to numberOfEvents - 1 do
    begin
        // Get the event from the event queue
        tEvent := ChantSR1.GetChantSREvent(0);
        case tEvent.ChantCallback of
            CCSRHasPhrase:
            begin
                numberOfRules := tEvent.GetResourceCount(CSRRule);
                for j := 0 to numberOfRules - 1 do
                begin
                    aChildTChantRule := tEvent.GetChantRule(j);
                    // Rules are a tree structure
                    ProcessRule(aChildTChantRule);
                end;
            end;
        end;
        // Remove the event from the event queue
        ChantSR1.RemoveResource(CSREvent, 0);
        tEvent.Destroy();
    end;
end;
procedure TForm1.ProcessRule(TChantRule aTChantRule)
var
numberOfRules: Integer;
aChildTChantRule: TChantRule;
j: Integer;
id: Integer;
name: string;
begin
    numberOfRules := aTChantRule.GetResourceCount(CSRRule);
    for j := 0 to numberOfRules - 1 do
    begin
        aChildTChantRule := aTChantRule.GetChantRule(j);
        // Rules are a tree structure
        ProcessRule(aChildTChantRule);
    end;
    // Process property values
    id := aTChantRule.ID;
    sName := aTChantRule.Name;
end;
    

public void hasEvent(Object obj1, Object obj2)
{
    // Get the number of events
    int numberOfEvents = JChantSR1.getResourceCount(ChantSpeechResource.CSREvent,0,0);
    for (int i = 0; i < numberOfEvents; i++)
    {
        // Get the event from the event queue
        JChantSREvent jChantSREvent = JChantSR1.getChantSREvent(0);
        // Process the type of callback event
        switch (jChantSREvent.getChantCallback())
        {
            case ChantCallback.CCSRHasPhrase :
            {
                int numberOfRules = jChantSREvent.getResourceCount(ChantSpeechResource.CSRRule);
                for (int j = 0; j < numberOfRules; j++)
                {
                    JChantRule jChantRule = jChantSREvent.getChantRule(j);
                    // Rules are a tree structure
                    processRule(jChantRule);                   
                }
            }
            default :
            break;
        }
        // Remove the event from the event queue
        JChantSR1.removeResource(ChantSpeechResource.CSREvent, 0, "");
    }	  
}
public void processRule(JChantRule jChantRule)
{
    int numberOfRules = jChantRule.getResourceCount(ChantSpeechResource.CSRRule);
    for (int j = 0; j < numberOfRules; j++)
    {
        JChantRule jChildChantRule = jChantRule.getChantRule(j);
        // Rules are a tree structure
        processRule(jChildChantRule);                   
    }
    // Process property values
    int id = jChantRule.getID();
    String name = jChantRule.getName();
}
    

<script language="javascript" for="WChantSR1" event="HasEvent"><!--
var wChantSREvent
var wChantRule
// Get the number of events
var numberOfEvents = WChantSR1.GetResourceCount(CSREvent);
for (i = 0; i < numberOfEvents; i++)
{
    // Get the event from the event queue
    wChantSREvent = WChantSR1.GetResource(CSREvent, 0);
    // Process the type of callback event
    switch (wChantSREvent.ChantCallback)
    {
        default :
            break;
        case CCSRHasPhrase :
            var numberOfRules = wChantSREvent.GetResourceCount(CSRRule);
            for (j = 0; j < numberOfRules; j++)
            {
                wChantRule = wChantSREvent.GetResource(CSRRule,j);
                // Rules are a tree structure
                ProcessRule(wChantRule);
            }
        break;
    }
    // Remove the event from the event queue
    WChantSR1.RemoveResource(CSREvent, 0);
}
function ProcessRule(WChantRule wChantRule)
{
    var numberOfRules = wChantRule.GetResourceCount(CSRRule);
    for (j = 0; j < numberOfRules; j++)
    {
        var wChildChantRule = wChantRule.GetResource(CSRRule,j);
        // Rules are a tree structure
        ProcessRule(wChildChantRule);
    }
    // Process property values
    var id = wChantRule.ID;
    var name = wChantRule.Name;
}
//-->
    

Private Sub XChantSR1_HasEvent()
Dim aXChantSREvent As XChantSREvent
Dim aXChantRule As XChantRule
Dim numberOfRules As Long
Dim I As Integer
Dim J As Integer
    ' Get the number of events
    numberOfRules = XChantSR1.GetResourceCount(CSREvent)
    For I = 0 To numberOfRules - 1
        ' Get the event from the event queue
        Set aXChantSREvent = XChantSR1.GetResource(CSREvent, 0)
        ' Process the type of callback event
        Select Case aXChantSREvent.ChantCallback
            Case CCSRHasPhrase
                numberOfRules = aXChantSREvent.GetResourceCount(CSRRule)
                For J = 0 To numberOfRules - 1
                    Set aXChantRule = aXChantSREvent.GetResource(CSRRule, J)
                    ' Rules are a tree structure
                    ProcessRule aXChantRule
                Next
            Case Else
        End Select
        ' Remove the event from the event queue
        XChantSR1.RemoveResource CSREvent, 0
    Next
End Sub
Private Sub ProcessRule(ByVal aXChantRule As XChantRule)
Dim aXChildChantRule As XChantRule
Dim numberOfRules As Long
Dim J As Integer
Dim id as Integer
Dim name As String
    numberOfRules = aXChantRule.GetResourceCount(CSRRule)
    For J = 0 To numberOfRules - 1
        Set aXChildChantRule = aXChantRule.GetResource(CSRRule, J)
        ' Rules are a tree structure
        ProcessRule aXChildChantRule
    Next
    ' Process property values
    id = aXChantRule.ID
    name = aXChantRule.Name
End Sub
        

Private Sub NChantSR1_HasEvent(ByVal sender As System.Object, ByVal e As SpeechKit.HasEventArgs) Handles NChantSR1.HasEvent
Dim nChantSREvent As NChantSREvent
Dim nChantRule As NChantRule
Dim numberOfEvents As Integer
Dim numberOfRules As Integer
Dim I As Integer
Dim J As Integer
' Get the number of events
numberOfEvents = NChantSR1.GetResourceCount(ChantSpeechResource.CSREvent, 0, 0)
For I = 0 To numberOfEvents - 1
    ' Get the event from the event queue
    nChantSREvent = NChantSR1.GetChantSREvent(0)
    ' Process the type of callback event
    Select Case nChantSREvent.ChantCallback
        Case ChantCallback.CCSRHasPhrase
            numberOfRules = nChantSREvent.GetResourceCount(ChantSpeechResource.CSRRule)
            For J = 0 To numberOfRules - 1
                nChantRule = nChantSREvent.GetChantRule(J)
                ' Rules are a tree structure
                ProcessRule(nChantRule)
                Next
            Next
        Case Else
    End Select
    ' Remove the event from the event queue
    NChantSR1.RemoveResource(ChantSpeechResource.CSREvent, 0, "")
Next
End Sub
Private Sub ProcessRule(ByVal nChantRule As NChantRule)
Dim nChildChantRule As NChantRule
Dim numberOfRules As Long
Dim J As Integer
Dim id as Integer
Dim name As String
numberOfRules = nChantRule.GetResourceCount(CSRRule)
For J = 0 To numberOfRules - 1
    nChildChantRule = nChantRule.GetChantRule(J)
    ' Rules are a tree structure
    ProcessRule(nChildChantRule)
Next
' Process property values
id = nChantRule.ID
name = nChantRule.Name
End Sub