⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 documentconverter.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
📖 第 1 页 / 共 3 页
字号:
       ParseException(L"exactly one of 'aai' or 'aaiexpr' may be specified");     break;   }    // (6) Verify the node.   ProcessNodeFinal(elemType); }   void DocumentConverter::endElement(const XMLCh* const uri,                                    const XMLCh* const localname,                                    const XMLCh* const qname) {   // (0) Just ignore this?   if (ignoreDepth > 0) {     --ignoreDepth;     return;   }    // (1) Copy this element or look it up?    // (1.1) Inside a <grammar>, we can blindly copy this data.   if (inGrammar && copyDepth == 0) inGrammar = false;   if (inGrammar) {     CopyElementClose(localname);     return;   }    // (1.2) Convert name string to integer value.   XMLChToVXIchar elementName(localname);    int elemType;   bool conversionFailed = !ConvertElement(elementName.c_str(), elemType);    // (1.3) Copy almost anything inside a <prompt>.   if (explicitPrompt) {     if (conversionFailed) {       CopyElementClose(localname);       return;     }     switch (elemType) {     case NODE_AUDIO:     case NODE_VALUE:     case NODE_ENUMERATE:       break;     case NODE_PROMPT:       doc->AddContent(L"</speak>", 8);       explicitPrompt = false;       break;     default:       CopyElementClose(localname);       return;     }   }    // (1.4) Print errors for all other conversion failures.   if (conversionFailed) {     vxistring temp(L"unrecognized element - ");     temp += elementName.c_str();     ParseException(temp.c_str());   }    // (2) Handle implicit prompts.    if (implicitPrompt) {     switch (elemType) {     case NODE_AUDIO:     case NODE_VALUE:     case NODE_ENUMERATE:       break;     case PRIV_ELEM_BREAK:   // These implicitly imply a prompt.     case PRIV_ELEM_EMPHASIS:     case PRIV_ELEM_MARK:     case PRIV_ELEM_PARAGRAPH:     case PRIV_ELEM_PHONEME:     case PRIV_ELEM_PROSODY:     case PRIV_ELEM_SAYAS:     case PRIV_ELEM_SENTENCE:     case PRIV_ELEM_VOICE:       CopyElementClose(localname);       return;     default:       EndImplicitPrompt();       break;     }   }    // (3) Reverse special handling from startElement()    switch (elemType) {   case NODE_CHOICE:          // These may have PCDATA which is not a prompt   case NODE_OPTION:     doc->PruneWhitespace();     pcdataImpliesPrompt = true;   case NODE_LOG:     pcdataImpliesPrompt = true;     break;   case NODE_SCRIPT:     pcdataImpliesPrompt = true;     // Intentional fall through!   case NODE_GRAMMAR:     if (contentForbidden ^ hasContent)       contentForbidden = false;     else       ParseException(L"either the 'src' attribute or inlined content "                      L"may be provided, not both");     break;   default:     break;   }    // (4) This element is complete.    try {     doc->EndElement();   }   catch (const VXMLDocumentModel::InternalError &) {     ParseException(L"corrupted document tree; unable to complete element");   } }   void DocumentConverter::characters(const XMLCh* const chars,                                    const unsigned int length) {   // (0) Just ignore this?   if (chars == NULL || length == 0 || ignoreDepth > 0) return;    // (1) Ignore non-empty prompts consisting of pure whitespace   unsigned int l;   for (l = 0; l < length; ++l) {     XMLCh c = chars[l];     if (c == ' ' || c == '\n' || c == '\r' || c == '\t') continue;     break;   }   if (l == length) return;    // (2) Is this an implicit prompt?   if (pcdataImpliesPrompt && !explicitPrompt && !implicitPrompt && !inGrammar)     StartImplicitPrompt();    // (3) Add content to the document model.   try {     // This conversion should be safe.  CDATA may only contain valid XML     // characters.  These are defined in the XML 1.0 specification as the set     // 0x9, 0xA, 0xD, 0x20-0xD7FF, 0xE000-0xFFFD, 0x10000-0x10FFFF.     XMLChToVXIchar data(chars);     hasContent = true;          unsigned int start = 0;     unsigned int pos = 0;     VXIchar c;     // We need to escape two characters: (<,&) -> (&lt;, &amp;)     if((inGrammar && (GetGrammarType().empty() || GetGrammarType() == L"application/srgs+xml")) ||         (explicitPrompt || implicitPrompt)         )      {       do {         c = *(data.c_str() + pos);         if (c == L'<') {           if (start != pos)              doc->AddContent(data.c_str() + start, pos - start);           start = pos + 1;           doc->AddContent(L"&lt;", 4);         }         else if (c == L'&') {           if (start != pos)              doc->AddContent(data.c_str() + start, pos - start);           start = pos + 1;           doc->AddContent(L"&amp;", 5);         }                  ++pos;       } while (c != L'\0');          if (pos > start)         doc->AddContent(data.c_str() + start, pos - start - 1); // -1 to kill off final \0        } else {       doc->AddContent(data.c_str(), wcslen(data.c_str()));     }   }   catch (const VXMLDocumentModel::OutOfMemory &) {     ParseException(L"unable to allocate memory for content");   }   catch (const VXMLDocumentModel::InternalError &) {     ParseException(L"corrupted document tree; unable to add content");   } }   void DocumentConverter::ignorableWhitespace(const XMLCh* const chars,                                             const unsigned int l) { }   void DocumentConverter::processingInstruction(const XMLCh* const target,                                               const XMLCh* const data) { }  //#############################################################################  void DocumentConverter::ProcessNodeAttribute(VXMLElementType elemType,                                              int attrType,                                              const VXIchar* const value) {   // This shouldn't ever happen, if it does, we'll just ignore it.   if (value == NULL) return;    switch (elemType) {   case NODE_BLOCK:   case NODE_FIELD:   case NODE_INITIAL:   case NODE_OBJECT:   case NODE_RECORD:   case NODE_TRANSFER:     // We associate a hidden interal name with this element.     if (attrType == ATTRIBUTE_NAME) attrType = ATTRIBUTE__ITEMNAME;     break;   case NODE_CLEAR:     if (attrType == ATTRIBUTE_NAMELIST && !value[0])       ParseException(L"the namelist attribute on clear cannot be empty");     break;   case NODE_FORM:   case NODE_MENU:     // We associate a hidden interal name with this element.     if (attrType == ATTRIBUTE_ID) attrType = ATTRIBUTE__ITEMNAME;     break;   case NODE_FILLED:     if (doc->GetParentType() != NODE_FORM)       ParseException(L"attributes valid on filled only at form level");     if (attrType == ATTRIBUTE_NAMELIST && !value[0])       ParseException(L"the namelist attribute on filled cannot be empty");     break;   case NODE_GRAMMAR:     if (doc->GetParentType() != NODE_FORM && attrType == ATTRIBUTE_SCOPE)       ParseException(L"the scope attribute is valid only on grammars at form "                      L"level");     break;   case NODE_SUBDIALOG:     // We associate a hidden interal name with this element.     if (attrType == ATTRIBUTE_NAME) attrType = ATTRIBUTE__ITEMNAME;     // modal was dropped in 2.0.     if (attrType == ATTRIBUTE_MODAL && version != 1.0f)       ParseException(L"the modal attribute on subdialog was dropped after "                      L"1.0");     break;   case NODE_VALUE:     if (attrType == ATTRIBUTE_EXPR) break;      if (doc->GetParentType() == NODE_LOG)       ParseException(L"only the expr attribute is valid on value elements "                      L"within a log element");  #pragma message("JC: Obsolete???")     /*     if (doc->GetParentType() == NODE_SAYAS)       ParseException(L"only the expr attribute is valid on value elements "                      L"within a say-as element");     */     break;   case NODE_VXML:     // version is processed elsewhere and may be ignored.     if (attrType == ATTRIBUTE_VERSION) return;     if (attrType == PRIV_ATTRIB_SCHEMALOC) return;     break;   default:     break;   }    // (4.3) Add the attribute to the element.    if (attrType > PRIV_ATTRIB_RangeStart)     ParseException(L"internal error during attribute processing");    doc->AddAttribute(VXMLAttributeType(attrType), value); }   void DocumentConverter::ProcessNodeFinal(VXMLElementType elemType) {   // Convert attributes.   vxistring attr;    switch (elemType) {   case NODE_BLOCK:   case NODE_FIELD:   case NODE_FORM:   case NODE_INITIAL:   case NODE_MENU:   case NODE_OBJECT:   case NODE_RECORD:   case NODE_SUBDIALOG:   case NODE_TRANSFER:     // Name the 'unnamed' elements as neccessary.     if (!doc->GetAttribute(ATTRIBUTE__ITEMNAME, attr)) {       vxistring variable;       VXMLDocumentModel::CreateHiddenVariable(variable);       doc->AddAttribute(ATTRIBUTE__ITEMNAME, variable);     }     break;   case NODE_FILLED:     if (!doc->GetAttribute(ATTRIBUTE_MODE, attr))       doc->AddAttribute(ATTRIBUTE_MODE, L"all");     break;   case NODE_VXML:   case DEFAULTS_ROOT:     VXMLDocumentModel::CreateHiddenVariable(attr);     doc->AddAttribute(ATTRIBUTE__ITEMNAME, attr);     break;   default:     break;   }    // Generate DTMF sequences for <choice> elements in <menu> if necessary.   if (elemType == NODE_MENU) {     if (doc->GetAttribute(ATTRIBUTE_DTMF, attr) && attr == L"true")       choiceNumber = 1;     else       choiceNumber = 0;   }    if (elemType == NODE_CHOICE && choiceNumber > 0 && choiceNumber < 10 &&       !doc->GetAttribute(ATTRIBUTE_DTMF, attr))   {     std::basic_stringstream<VXIchar> countString;     countString << choiceNumber;     doc->AddAttribute(ATTRIBUTE_DTMF, countString.str());     ++choiceNumber;   }    if (elemType == NODE_PROMPT) {     vxistring base, lang;     doc->GetAttribute(ATTRIBUTE_BASE, base);     doc->GetAttribute(ATTRIBUTE_XMLLANG, lang);      doc->AddContent(L"<?xml version='1.0'?><speak version='1.0' xmlns="                     L"'http://www.w3.org/2001/10/synthesis' xml:base='", 96);     doc->AddContent(base.c_str(), base.length());     doc->AddContent(L"' xml:lang='", 12);     doc->AddContent(lang.c_str(), lang.length());     doc->AddContent(L"'>", 2);   } }   void DocumentConverter::CopyElementStart(const XMLCh* const localname,                                          const Attributes &attrs) {   ++copyDepth;    doc->AddContent(L"<", 1);    XMLChToVXIchar data(localname);   doc->AddContent(data.c_str(), wcslen(data.c_str()));    for (unsigned int index = 0; index < attrs.getLength(); ++index) {     doc->AddContent(L" ", 1);      // Determine the attribute name     if (Compare(attrs.getQName(index), L"xml:lang"))       doc->AddContent(L"xml:lang", 8);      else {       XMLChToVXIchar name(attrs.getLocalName(index));       doc->AddContent(name.c_str(), wcslen(name.c_str()));     }            doc->AddContent(L"=\"", 2);      XMLChToVXIchar value(attrs.getValue(index));      unsigned int start = 0;     unsigned int pos = 0;     VXIchar c;     // We need to escape three characters: (<,>,&) -> (&lt;,&gt;,&amp;)     do {       c = *(value.c_str() + pos);       if (c == L'<') {         if (start != pos)            doc->AddContent(value.c_str() + start, pos - start);         start = pos + 1;         doc->AddContent(L"&lt;", 4);       }       else if (c == L'>') {         if (start != pos)            doc->AddContent(value.c_str() + start, pos - start);         start = pos + 1;         doc->AddContent(L"&gt;", 4);       }       else if (c == L'&') {         if (start != pos)            doc->AddContent(value.c_str() + start, pos - start);         start = pos + 1;         doc->AddContent(L"&amp;", 5);       }              ++pos;     } while (c != L'\0');      if (pos > start)       doc->AddContent(value.c_str() + start, pos - start - 1); // -1 to kill off final \0      doc->AddContent(L"\"", 1);   }    doc->AddContent(L">", 1); }   void DocumentConverter::CopyElementClose(const XMLCh* const localname) {   doc->AddContent(L"</", 2);    XMLChToVXIchar data(localname);   doc->AddContent(data.c_str(), wcslen(data.c_str()));    doc->AddContent(L">", 1);    --copyDepth; }   void DocumentConverter::StartImplicitPrompt() {   implicitPrompt = true;   doc->StartElement(NODE_PROMPT);    doc->AddContent(L"<?xml version='1.0'?><speak version='1.0' xmlns="                   L"'http://www.w3.org/2001/10/synthesis' xml:base='", 96);   doc->AddContent(baseUri.c_str(), baseUri.length());   doc->AddContent(L"' xml:lang='", 12);   doc->AddContent(documentLang.c_str(), documentLang.length());   doc->AddContent(L"'>", 2);    copyDepth = 0; }   void DocumentConverter::EndImplicitPrompt() {   doc->AddContent(L"</speak>", 8);   doc->EndElement();   implicitPrompt = false; }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -