📄 documentconverter.cpp
字号:
for (unsigned int index = 0; index < attrs.getLength(); ++index) { if (!Compare(attrs.getName(index), L"version")) continue; const XMLCh * attributeValue = attrs.getValue(index); if (Compare(attributeValue, L"1.0")) version = 1.0f; else if (Compare(attributeValue, L"2.0")) version = 2.0f; else ParseException(L"illegal version"); break; } break; } case PRIV_ELEM_DIV: case PRIV_ELEM_EMP: case PRIV_ELEM_PROS: case PRIV_ELEM_SAYAS: if (version != 1.0f) { vxistring temp(L"support for element '"); temp += elementName.c_str(); temp += L"' was dropped after VXML 1.0"; ParseException(temp.c_str()); } break; default: break; } // (2.2) Should we just ignore this node? if (IsIgnorable(elemType)) return; // (2.3) Convert nodes as necessary. switch (elemType) { case PRIV_ELEM_DIV: // Convert <div> into either <p> or <s>. if (attrs.getLength() == 1 && Compare(attrs.getName(0), L"paragraph")) elemType = NODE_PARAGRAPH; else elemType = NODE_SENTENCE; break; case PRIV_ELEM_EMP: elemType = NODE_EMPHASIS; break; case PRIV_ELEM_SAYAS: { elemType = NODE_SAYAS; for (unsigned int index = 0; index < attrs.getLength(); ++index) if (Compare(attrs.getName(index), L"phon")) { elemType = NODE_PHONEME; break; } break; } default: break; } // (3) Create new element. if (elemType > PRIV_ELEM_RangeStart) { vxistring temp(L"internal error for element - "); temp += elementName.c_str(); ParseException(temp.c_str()); } try { doc->StartElement(VXMLElementType(elemType)); } catch (const VXMLDocumentModel::OutOfMemory &) { ParseException(L"unable to allocate memory for element"); } catch (const VXMLDocumentModel::InternalError &) { ParseException(L"corrupted document tree; unable to add element"); } // (4) Add attributes to element. for (unsigned int index = 0; index < attrs.getLength(); ++index) { int attrType; // (4.1) Convert string to integer. XMLChToVXIchar attributeName(attrs.getName(index)); if (!ConvertAttribute(attributeName.c_str(), attrType)) { vxistring temp(L"unrecognized attribute - "); temp += attributeName.c_str(); ParseException(temp.c_str()); } // (4.2) Handle a few global settings. switch (attrType) { case PRIV_ATTRIB_CACHING: if (version != 1.0f) ParseException(L"the caching attribute was replaced by maxage and " L"maxstale after VXML 1.0"); if (Compare(attrs.getValue(index), L"safe")) { vxistring attr; if (!doc->GetAttribute(ATTRIBUTE_MAXAGE, attr)) doc->AddAttribute(ATTRIBUTE_MAXAGE, L"0"); } continue; default: break; } // (4.3) Handle internal values. XMLChToVXIchar attributeValue(attrs.getValue(index)); ProcessNodeAttribute(VXMLElementType(elemType), attrType, attributeValue.c_str()); } // (5) Verify the node. ProcessNodeFinal(VXMLElementType(elemType));}void DocumentConverter::endElement(const XMLCh* const name){ XMLChToVXIchar elementName(name); int elemType; if (!ConvertElement(elementName.c_str(), elemType)) { vxistring temp(L"unrecognized element - "); temp += elementName.c_str(); ParseException(temp.c_str()); } if (IsIgnorable(elemType)) return; 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){ // Should we just ignore these characters? if (ignoreDepth > 0) return; // Ignore 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; 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); 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){ }VXMLDocumentRep * DocumentConverter::GetDocument(){ VXMLDocumentRep * temp = doc; doc = NULL; return temp;}//#############################################################################bool DocumentConverter::IsIgnorable(int elemType){ switch (elemType) { case NODE_MARK: // 2.0 spec directs that this element be ignored case NODE_META: // Just ignore meta data case PRIV_ELEM_PROS: // <pros> does not convert to <prosody> cleanly return true; default: break; } return false;}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_BREAK: // msecs was replaced by time in 2.0 if (attrType == PRIV_ATTRIB_MSECS) { if (version != 1.0f) ParseException(L"the msec attribute on break was dropped after 1.0"); vxistring temp(value); temp += L"ms"; doc->AddAttribute(ATTRIBUTE_TIME, temp); return; } break; 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: case NODE_DTMF: 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_PARAGRAPH: case NODE_SENTENCE: // This is an artifact of converting <div> from 1.0. if (attrType == ATTRIBUTE_TYPE) return; case NODE_PHONEME: if (attrType == PRIV_ATTRIB_PHON) { doc->AddAttribute(ATTRIBUTE_ALPHABET, L"ipa"); attrType = ATTRIBUTE_PH; } // This is an artifact of the conversion of <sayas> from 1.0. if (attrType != ATTRIBUTE_PH && attrType != ATTRIBUTE_ALPHABET) return; break; case NODE_SAYAS: // phon is processed elsewhere and may be ingored if (attrType == PRIV_ATTRIB_PHON) return; // This shouldn't happen. // class was replaced by type in 2.0; <sayas> from 1.0 was replaced by // <say-as> in 2.0. if (attrType == PRIV_ATTRIB_CLASS) { vxistring temp(value); if (version == 1.0f) { // Convert 1.0 values. if (temp == L"phone") temp = L"telephone"; else if (temp == L"literal") temp = L"acronym"; else if (temp == L"digits") temp = L"number:digits"; } doc->AddAttribute(ATTRIBUTE_TYPE, temp); return; } 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"); if (doc->GetParentType() == NODE_SAYAS) ParseException(L"only the expr attribute is valid on value elements " L"within a say-as element"); if (version != 1.0f) ParseException(L"after 1.0, only the expr attribute is allowed on value " L"elements"); // Ignore recsrc & mode. if (attrType == PRIV_ATTRIB_RECSRC || attrType == ATTRIBUTE_MODE) return; // class was replaced by type in 2.0 if (attrType == PRIV_ATTRIB_CLASS) { vxistring temp(value); if (temp == L"phone") temp = L"telephone"; else if (temp == L"literal") temp = L"acronym"; else if (temp == L"digits") temp = L"number:digits"; doc->AddAttribute(ATTRIBUTE_TYPE, temp); return; } break; case NODE_VXML: // version is processed elsewhere and may be ignored. if (attrType == PRIV_ATTRIB_VERSION) return; // lang was replaced by xml:lang in 2.0 if (attrType == PRIV_ATTRIB_LANG) { if (version != 1.0f) ParseException(L"the lang attribute on vxml was dropped after 1.0"); attrType = ATTRIBUTE_XMLLANG; } 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -