📄 documentconverter.cpp
字号:
switch (rawElemType) {
case PRIV_ELEM_ERROR:
ProcessNodeAttribute(elemType, ATTRIBUTE_EVENT, L"error");
break;
case PRIV_ELEM_HELP:
ProcessNodeAttribute(elemType, ATTRIBUTE_EVENT, L"help");
break;
case PRIV_ELEM_NOINPUT:
ProcessNodeAttribute(elemType, ATTRIBUTE_EVENT, L"noinput");
break;
case PRIV_ELEM_NOMATCH:
ProcessNodeAttribute(elemType, ATTRIBUTE_EVENT, L"nomatch");
break;
default:
break;
}
bool foundResourceBaseURI = false;
bool foundResourceBaseLang = false;
for (unsigned int index = 0; index < attrs.getLength(); ++index) {
// (4.2) Convert string to integer.
int attrType;
XMLChToVXIchar attributeName(attrs.getLocalName(index));
//#pragma message("JC: This is a temporary hack!")
if (Compare(attrs.getQName(index), L"xml:lang"))
attrType = ATTRIBUTE_XMLLANG;
else if (!ConvertAttribute(attributeName.c_str(), attrType)) {
vxistring temp(L"unrecognized attribute - ");
temp += attributeName.c_str();
ParseException(temp.c_str());
}
// (4.3) Impose attribute restrictions not representable in schema 1.0.
switch (elemType) {
case NODE_AUDIO:
if (attrType == ATTRIBUTE_SRC) ++attrGroup1;
if (attrType == ATTRIBUTE_EXPR) ++attrGroup1;
break;
case NODE_CHOICE:
case NODE_LINK:
if (attrType == ATTRIBUTE_NEXT) ++attrGroup1;
if (attrType == ATTRIBUTE_EXPR) ++attrGroup1;
if (attrType == ATTRIBUTE_EVENT) ++attrGroup1;
if (attrType == ATTRIBUTE_EVENTEXPR) ++attrGroup1;
// and...
if (attrType == ATTRIBUTE_MESSAGE) ++attrGroup2;
if (attrType == ATTRIBUTE_MESSAGEEXPR) ++attrGroup2;
break;
case NODE_EXIT:
if (attrType == ATTRIBUTE_EXPR) ++attrGroup1;
if (attrType == ATTRIBUTE_NAMELIST) ++attrGroup1;
break;
case NODE_GOTO:
if (attrType == ATTRIBUTE_NEXT) ++attrGroup1;
if (attrType == ATTRIBUTE_EXPR) ++attrGroup1;
if (attrType == ATTRIBUTE_NEXTITEM) ++attrGroup1;
if (attrType == ATTRIBUTE_EXPRITEM) ++attrGroup1;
break;
case NODE_GRAMMAR:
if (attrType == ATTRIBUTE_SRC) contentForbidden = true;
break;
case NODE_META:
if (attrType == ATTRIBUTE_NAME) ++attrGroup1;
if (attrType == ATTRIBUTE_HTTP_EQUIV) ++attrGroup1;
break;
case NODE_PARAM:
if (attrType == ATTRIBUTE_EXPR) ++attrGroup1;
if (attrType == ATTRIBUTE_VALUE) ++attrGroup1;
break;
case NODE_RETURN:
if (attrType == ATTRIBUTE_EVENT) ++attrGroup1;
if (attrType == ATTRIBUTE_EVENTEXPR) ++attrGroup1;
if (attrType == ATTRIBUTE_NAMELIST) ++attrGroup1;
// and...
if (attrType == ATTRIBUTE_MESSAGE) ++attrGroup2;
if (attrType == ATTRIBUTE_MESSAGEEXPR) ++attrGroup2;
break;
case NODE_SCRIPT:
if (attrType == ATTRIBUTE_SRC) contentForbidden = true;
break;
case NODE_SUBDIALOG:
if (attrType == ATTRIBUTE_SRC) ++attrGroup1;
if (attrType == ATTRIBUTE_SRCEXPR) ++attrGroup1;
break;
case NODE_SUBMIT:
if (attrType == ATTRIBUTE_NEXT) ++attrGroup1;
if (attrType == ATTRIBUTE_EXPR) ++attrGroup1;
break;
case NODE_THROW:
if (attrType == ATTRIBUTE_EVENT) ++attrGroup1;
if (attrType == ATTRIBUTE_EVENTEXPR) ++attrGroup1;
// and...
if (attrType == ATTRIBUTE_MESSAGE) ++attrGroup2;
if (attrType == ATTRIBUTE_MESSAGEEXPR) ++attrGroup2;
break;
case NODE_TRANSFER:
if (attrType == ATTRIBUTE_DEST) ++attrGroup1;
if (attrType == ATTRIBUTE_DESTEXPR) ++attrGroup1;
// and...
if (attrType == ATTRIBUTE_AAI) ++attrGroup2;
if (attrType == ATTRIBUTE_AAIEXPR) ++attrGroup2;
break;
}
// Handle base URI resolution and xml:lang for <prompt> & <grammar>
switch (elemType) {
case NODE_PROMPT:
case NODE_GRAMMAR:
if (attrType == ATTRIBUTE_XMLLANG) foundResourceBaseLang = true;
else if (attrType == ATTRIBUTE_BASE) foundResourceBaseURI = true;
else if (attrType == ATTRIBUTE_TYPE) {
// set grammar type for this grammar element
XMLChToVXIchar attributeValue(attrs.getValue(index));
SetGrammarType(attributeValue.c_str());
}
break;
case NODE_VXML:
if (attrType == ATTRIBUTE_BASE) {
XMLChToVXIchar attributeValue(attrs.getValue(index));
SetBaseUri(attributeValue.c_str());
continue;
}
else if (attrType == ATTRIBUTE_XMLLANG) {
XMLChToVXIchar attributeValue(attrs.getValue(index));
documentLang = attributeValue.c_str();
continue;
}
break;
case DEFAULTS_ROOT:
if (attrType == ATTRIBUTE_XMLLANG) {
XMLChToVXIchar attributeValue(attrs.getValue(index));
defaultLang = attributeValue.c_str();
documentLang = defaultLang;
continue;
}
break;
}
// (4.5) Handle internal values.
XMLChToVXIchar attributeValue(attrs.getValue(index));
ProcessNodeAttribute(elemType, attrType, attributeValue.c_str());
}
// Use the default language for this document if necessary.
if (elemType == NODE_VXML && documentLang.empty())
documentLang = defaultLang;
// Assign an xml:base and/or xml:lang if not already specified for every
// <grammar>, <prompt>, and <field> (because of builtins).
if (elemType == NODE_PROMPT || elemType == NODE_GRAMMAR ||
elemType == NODE_FIELD || elemType == NODE_MENU)
{
if (!foundResourceBaseURI)
doc->AddAttribute(ATTRIBUTE_BASE, baseUri.c_str());
if (!foundResourceBaseLang)
doc->AddAttribute(ATTRIBUTE_XMLLANG, documentLang.c_str());
}
// (5) Generate errors for attribute restrictions.
switch (elemType) {
case NODE_AUDIO:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'src' or 'expr' must be specified");
break;
case NODE_CHOICE:
case NODE_LINK:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'next', 'expr', 'event' or 'eventexpr' "
L"must be specified");
if (attrGroup2 > 1)
ParseException(L"exactly one of 'message' or 'messageexpr' "
L"may be specified");
break;
case NODE_EXIT:
if (attrGroup1 > 1)
ParseException(L"exactly one of 'expr' or 'namelist' "
L"may be specified");
break;
case NODE_GOTO:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'next', 'expr', 'nextitem' or 'expritem'"
L" must be specified");
break;
case NODE_META:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'name' or 'http-equiv' "
L"must be specified");
break;
case NODE_PARAM:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'expr' or 'value' must be specified");
break;
case NODE_RETURN:
if (attrGroup1 > 1)
ParseException(L"exactly one of 'event', 'eventexpr' or 'namelist' "
L"may be specified");
if (attrGroup2 > 1)
ParseException(L"exactly one of 'message' or 'messageexpr' "
L"may be specified");
break;
case NODE_SUBDIALOG:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'src' or 'srcexpr' must be specified");
break;
case NODE_SUBMIT:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'next' or 'expr' must be specified");
break;
case NODE_THROW:
if (attrGroup1 != 1)
ParseException(L"exactly one of 'event' or 'eventexpr' "
L"must be specified");
if (attrGroup2 > 1)
ParseException(L"exactly one of 'message' or 'messageexpr' "
L"may be specified");
break;
case NODE_TRANSFER:
if (attrGroup1 > 1)
ParseException(L"exactly one of 'dest' or 'destexpr' may be specified");
if (attrGroup2 > 1)
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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -