Sapi如何在标签元素c ++中获取元素

时间:2014-12-30 08:01:37

标签: sapi

我正在研究SAPI 5.4这是我的语法规则

<RULE ID="FIRST_TRANSMISSION" TOPLEVEL="ACTIVE">
    <P><RULEREF REFID="BATTERY"/></P>
    <P><RULEREF REFID="FO"/></P>
    <P><RULEREF REFID="MISSION"/></P>  
</RULE>

我使用c ++代码来获取识别的单词是我的代码的和平。我的规则ID = 256

case 256:
                {
                    if (SUCCEEDED (hr))
                    {
                        hr = pISpRecoResult->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &pwszText, NULL);
                    }           

                    char ch[260];
                    char DefChar = ' ';
                    WideCharToMultiByte(CP_ACP,0,pwszText,-1, ch,260,&DefChar, NULL);                       
                    string ss(ch);          
                    str.append(ss);

                    break;
                }

现在我想根据子规则获得认可的单词。 例如: - 我想在语法文件中根据<P><RULEREF REFID="FO"/></P>这个阶段得到识别的单词。我怎么能这样做

1 个答案:

答案 0 :(得分:0)

您需要使用ISpRecoResult::GetPhrase来检索与识别相关联的SPPHRASE。然后,您可以使用SPPHRASE的Rule字段遍历与识别相关的规则,直到找到ID为“FO”的规则。一旦找到了合适的SPPHRASERULE,该规则就会有与之关联的单词索引,您可以像以前一样调用ISpRecoResult::GetText

代码看起来像这样:(注意 - 我实际上没有编译它,因此可能会出错。)

SPPHRASE* pPhrase;
hr = pRecoResult->GetPhrase(&pPhrase);
if (SUCCEEDED(hr))
{
    ULONG ulFirstElement = 0;
    ULONG ulCountOfElements = 0;
    hr = FindRuleMatching(&pPhrase->Rule, L"FO", &ulFirstElement, &ulCountOfElements);
    if (SUCCEEDED(hr))
    {
        LPWSTR pwszText;
        hr = pRecoResult->GetText(ulFirstElement, ulCountOfElements, TRUE, &pwszText, NULL);
        if (SUCCEEDED(hr))
        {
             // do stuff
             ::CoTaskMemFree(pwszText);
        }
    }
    ::CoTaskMemFree(pPhrase);
}


HRESULT
FindRuleMatching(const SPPHRASERULE* pRule, LPCWSTR szRuleName, ULONG* pulFirst, ULONG* pulCount)
{
    if (pRule == NULL)
    {
        return E_FAIL;
    }
    // depth-first search.  
    if (wcscmp(pRule->pszName, szRuleName) == 0)
    {
        *pulFirst = pRule->ulFirstElement;
        *pulCount = pRule->ulCountOfElements;
        return S_OK;
    }
    else if (SUCCEEDED(FindRuleMatching(pRule->pFirstChild, szRuleName, pulFirst, pulCount)))
    {
        return S_OK;
    }
    else return FindRuleMatching(pRule->pNextSibling, szRuleName, pulFirst, pulCount);
}