📄 mcbxml.c
字号:
*********************************************************
* Cache whether this new element is a declaration or not
*********************************************************
*/
nDeclaration = type == eTokenDeclaration;
/*
*********************************************************
* If we have node text then add this to the element
*********************************************************
*/
if (lpszText)
{
cbTemp = token.pStr - lpszText;
McbFindEndOfText(lpszText, &cbTemp);
McbAddText(pElement, McbStrdup(lpszText, cbTemp),
McbGROWBY);
#ifdef McbSTOREOFFSETS
pElement->pEntries[pElement->nSize-1].nStringOffset
= lpszText - pXML->lpXML;
#endif /* McbSTOREOFFSETS */
lpszText = NULL;
}
/*
*********************************************************
* Find the name of the tag
*********************************************************
*/
token = McbGetNextToken(pXML, &cbToken, &type);
/*
*********************************************************
* Return an error if we couldn't obtain the next token or
* it wasnt text
*********************************************************
*/
if (type != eTokenText)
{
pXML->error = eXMLErrorMissingTagName;
return FALSE;
}
/*
*********************************************************
* If we found a new element which has the same as this
* element then we need to pass this back to the caller..
*********************************************************
*/
if (pElement->lpszName &&
_tcsnicmp(pElement->lpszName, token.pStr,
_tcslen(pElement->lpszName)) == 0)
{
/*
*****************************************************
* Indicate to the caller that it needs to create a
* new element.
*****************************************************
*/
pXML->lpNewElement = token.pStr;
pXML->cbNewElement = cbToken;
return TRUE;
}
/*
*********************************************************
* If the name of the new element differs from the name of
* the current element we need to add the new element to
* the current one and recurse
*********************************************************
*/
else
{
/*
*****************************************************
* Now we need to add the new element and recurse
*****************************************************
*/
pNew = McbAddElement(pElement,
McbStrdup(token.pStr, cbToken), nDeclaration,
McbGROWBY);
#ifdef McbSTOREOFFSETS
pElement->pEntries[pElement->nSize-1].nStringOffset =
token.pStr - pXML->lpXML;
#endif /* McbSTOREOFFSETS */
while(pNew)
{
/*
*************************************************
* Callself to process the new node. If we return
* FALSE this means we dont have any more
* processing to do...
*************************************************
*/
if (!McbParseXMLElement(pXML, pNew))
{
return FALSE;
}
else
{
/*
*********************************************
* If the call to recurse this function
* evented in a end tag specified in XML then
* we need to unwind the calls to this
* function until we find the appropriate node
* (the element name and end tag name must
* match)
*********************************************
*/
if (pXML->cbEndTag)
{
/*
*****************************************
* If we are back at the root node then we
* have an unmatched end tag
*****************************************
*/
if (!pElement->lpszName)
{
pXML->error =
eXMLErrorUnmatchedEndTag;
return FALSE;
}
/*
*****************************************
* If the end tag matches the name of this
* element then we only need to unwind
* once more...
*****************************************
*/
if (_tcsnicmp(pXML->lpEndTag,
pElement->lpszName,
_tcslen(pElement->lpszName)) == 0)
{
pXML->cbEndTag = 0;
}
return TRUE;
}
/*
*********************************************
* If the call indicated a new element is to
* be created on THIS element.
*********************************************
*/
else if (pXML->cbNewElement)
{
/*
*****************************************
* If the name of this element matches the
* name of the element we need to create
* then we need to return to the caller
* and let it process the element.
*****************************************
*/
if (_tcsnicmp(pXML->lpNewElement,
pElement->lpszName,
_tcslen(pElement->lpszName)) == 0)
{
return TRUE;
}
/*
*****************************************
* Add the new element and recurse
*****************************************
*/
pNew = McbAddElement(pElement,
McbStrdup(pXML->lpNewElement,
pXML->cbNewElement), FALSE,
McbGROWBY);
#ifdef McbSTOREOFFSETS
pElement->pEntries[pElement->nSize-1].
nStringOffset =
pXML->lpNewElement - pXML->lpXML;
#endif /* McbSTOREOFFSETS */
pXML->cbNewElement = 0;
}
/*
*********************************************
* If we didn't have a new element to create
*********************************************
*/
else
{
pNew = NULL;
}
}
}
}
break;
/*
*************************************************************
* If we found an end tag
*************************************************************
*/
case eTokenTagEnd:
/*
*********************************************************
* If we have node text then add this to the element
*********************************************************
*/
if (lpszText)
{
cbTemp = token.pStr - lpszText;
McbFindEndOfText(lpszText, &cbTemp);
McbAddText(pElement, McbStrdup(lpszText, cbTemp),
McbGROWBY);
#ifdef McbSTOREOFFSETS
pElement->pEntries[pElement->nSize-1].nStringOffset
= lpszText - pXML->lpXML;
#endif /* McbSTOREOFFSETS */
lpszText = NULL;
}
/*
*********************************************************
* Find the name of the end tag
*********************************************************
*/
token = McbGetNextToken(pXML, &cbTemp, &type);
/*
*********************************************************
* The end tag should be text
*********************************************************
*/
if (type != eTokenText)
{
pXML->error = eXMLErrorMissingEndTagName;
return FALSE;
}
lpszTemp = token.pStr;
/*
*********************************************************
* After the end tag we should find a closing tag
*********************************************************
*/
token = McbGetNextToken(pXML, &cbToken, &type);
if (type != eTokenCloseTag)
{
pXML->error = eXMLErrorMissingEndTagName;
return FALSE;
}
/*
*********************************************************
* We need to return to the previous caller. If the name
* of the tag cannot be found we need to keep returning to
* caller until we find a match
*********************************************************
*/
if (_tcsnicmp(lpszTemp, pElement->lpszName,
_tcslen(pElement->lpszName)) != 0)
{
pXML->lpEndTag = lpszTemp;
pXML->cbEndTag = cbTemp;
}
/*
*********************************************************
* Return to the caller
*********************************************************
*/
return TRUE;
/*
*************************************************************
* If we found a clear (unformatted) token
*************************************************************
*/
case eTokenClear:
/*
*********************************************************
* If we have node text then add this to the element
*********************************************************
*/
if (lpszText)
{
cbTemp = token.pStr - lpszText;
McbFindEndOfText(lpszText, &cbTemp);
McbAddText(pElement, McbStrdup(lpszText, cbTemp),
McbGROWBY);
#ifdef McbSTOREOFFSETS
pElement->pEntries[pElement->nSize-1].nStringOffset
= lpszText - pXML->lpXML;
#endif /* McbSTOREOFFSETS */
lpszText = NULL;
}
if (!McbParseClearTag(pXML, pElement, token.pClr))
{
return FALSE;
}
break;
/*
*************************************************************
* Errors...
*************************************************************
*/
case eTokenCloseTag: /* '>' */
case eTokenShortHandClose: /* '/>' */
pXML->error = eXMLErrorUnexpectedToken;
return FALSE;
}
break;
/*
*****************************************************************
* If we are inside a tag definition we need to search for
* attributes
*****************************************************************
*/
case eInsideTag:
/*
*************************************************************
* Check what part of the attribute (name, equals, value) we
* are looking for.
*************************************************************
*/
switch(attrib)
{
/*
************************************************************
* If we are looking for a new attribute
************************************************************
*/
case eAttribName:
/*
*********************************************************
* Check what the current token type is
*********************************************************
*/
switch(type)
{
/*
*********************************************************
* If the current type is text...
* Eg. 'attribute'
*********************************************************
*/
case eTokenText:
/*
*****************************************************
* Cache the token then indicate that we are next to
* look for the equals
*****************************************************
*/
lpszTemp = token.pStr;
cbTemp = cbToken;
attrib = eAttribEquals;
break;
/*
*********************************************************
* If we found a closing tag...
* Eg. '>'
*********************************************************
*/
case eTokenCloseTag:
/*
*****************************************************
* We are now outside the tag
*****************************************************
*/
status = eOutsideTag;
break;
/*
*********************************************************
* If we found a short hand '/>' closing tag then we can
* return to the caller
*********************************************************
*/
case eTokenShortHandClose:
return TRUE;
/*
*********************************************************
* Errors...
*********************************************************
*/
case eTokenQuotedText: /* '"SomeText"' */
case eTokenTagStart: /* '<' */
case eTokenTagEnd: /* '</' */
case eTokenEquals: /* '=' */
case eTokenDeclaration: /* '<?' */
case eTokenClear:
pXML->error = eXMLErrorUnexpectedToken;
return FALSE;
}
break;
/*
************************************************************
* If we are looking for an equals
************************************************************
*/
case eAttribEquals:
/*
*********************************************************
* Check what the current token type is
*********************************************************
*/
switch(type)
{
/*
*********************************************************
* If the current type is text...
* Eg. 'Attribute AnotherAttribute'
*********************************************************
*/
case eTokenText:
/*
*****************************************************
* Add the unvalued attribute to the list
*****************************************************
*/
McbAddAttribute(pElement, McbStrdup(lpszTemp,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -