📄 ospxmlparse.c
字号:
/**########################################################################*########################################################################*########################################################################* * COPYRIGHT (c) 1998, 1999 by TransNexus, LLC * * This software contains proprietary and confidential information * of TransNexus, LLC. Except as may be set forth in the license * agreement under which this software is supplied, use, disclosure, * or reproduction is prohibited without the prior, express, written* consent of TransNexus, LLC. * *******#########################################################################*#########################################################################*#########################################################################*//* * ospxmlparse.c - Generic XML document parsing functions. */#include "osp.h"#include "ospbfr.h"#include "osplist.h"#include "ospxmlattr.h"#include "ospxmlelem.h"#include "osperrno.h"#include "ospxmltype.h"#include "ospxmldoc.h"#include "ospmsgelem.h"/**//*-----------------------------------------------------------------------* * OSPPXMLDocParse() - parse a document into its elements and attributes *-----------------------------------------------------------------------*/unsigned /* returns error code */OSPPXMLDocParse( OSPTBFR **ospvBfrAddr, /* buffer containing document */ OSPTXMLELEM **ospvElemAddr /* where to put parsed element */){ unsigned ospvErrCode = OSPC_ERR_NO_ERROR; OSPTXMLENC encoding = ospeXMLEncUnknown; OSPTXMLELEM *ospvParent = OSPC_OSNULL; if (ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (*ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (ospvElemAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* Before doing anything else, determine the encoding in use */ ospvErrCode = OSPPXMLDocGetEncoding(ospvBfrAddr, &encoding); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (encoding == ospeXMLEncUnknown) { /* * If we couldn't recognize the encoding, then punt by * indicating an error. */ ospvErrCode = OSPC_ERR_XML_BAD_ENC; } } /* * Now skip over the prolog; for now, we don't do any processing * of information in the prolog (e.g. document type definitions). */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocSkipProlog(ospvBfrAddr,encoding); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * Now that we've gotten past the prolog, we can start parsing the * document. */ ospvErrCode = OSPPXMLDocParseElem(ospvBfrAddr, encoding, &ospvParent); /* Now that we have the element, let's bypass the first (message) element * for now. Before we bypass it make sure it is a Message element and not * tokeninfo. */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { if(OSPPMsgGetElemPart(OSPPXMLElemGetName(ospvParent)) == ospeElemMessage) { *ospvElemAddr = (OSPTXMLELEM *)OSPPXMLElemFirstChild(ospvParent); ospvParent->ospmXMLElemChild = OSPC_OSNULL; OSPPXMLElemDelete(&ospvParent); } else { *ospvElemAddr = ospvParent; } } } return(ospvErrCode);}/**//*-----------------------------------------------------------------------* * OSPPXMLDocParseElem() - parse a document element *-----------------------------------------------------------------------*/unsigned /* returns error code */OSPPXMLDocParseElem( OSPTBFR **ospvBfrAddr, /* buffer containing document */ OSPTXMLENC ospvEncoding, /* character encoding for the document */ OSPTXMLELEM **ospvElemAddr /* where to put parsed element */){ /******************************************************************/ /***** CAUTION: This function is called recursively; be sure *****/ /***** to account for that in any modifications *****/ /******************************************************************/ unsigned ospvErrCode = OSPC_ERR_NO_ERROR; OSPTXMLELEM *elem = OSPC_OSNULL; OSPTXMLATTR *attr = OSPC_OSNULL; OSPTBFR *nameBfr = OSPC_OSNULL; OSPTBFR *valBfr = OSPC_OSNULL; OSPTLIST attrList = OSPC_OSNULL; OSPTLIST childList = OSPC_OSNULL; unsigned char readChar = '\0'; if (ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (*ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (ospvEncoding == ospeXMLEncUnknown) { ospvErrCode = OSPC_ERR_XML_BAD_ENC; } if (ospvElemAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* set up some of our local variables */ nameBfr = OSPPBfrNew(OSPC_XMLDOC_NAMESIZE); valBfr = OSPPBfrNew(OSPC_XMLDOC_VALUESIZE); OSPPListNew(&attrList); OSPPListNew(&childList); /* make sure the initializations went okay */ if ((nameBfr == OSPC_OSNULL) || (valBfr == OSPC_OSNULL)) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } /* to start out, skip until we've found the opening tag */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocSkipPastChar(ospvBfrAddr, ospvEncoding, OSPC_XMLDOC_OPEN); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * We've found the start of the name, so extract it. Note * that we use a message buffer to store the name. We do * that because message buffers serve as a convenient * "elastic" buffer and we don't have to know how big the * name is in advance. */ ospvErrCode = OSPPXMLDocGetName(ospvBfrAddr, ospvEncoding, &nameBfr); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * The next thing to get is attributes (if there are any). * We'll collect those in a local list for now, and then * add them to the real element when we've got all the * information for it. */ ospvErrCode = OSPPXMLDocGetAttrs(ospvBfrAddr, ospvEncoding, &attrList); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * Skip past any trailing whitespace to get to the end of the * element tag. */ ospvErrCode = OSPPXMLDocSkipWhite(ospvBfrAddr, ospvEncoding); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * Look at the next character to see if we've got an empty * element or not. */ ospvErrCode = OSPPXMLDocReadChar(ospvBfrAddr, ospvEncoding, &readChar); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (readChar == OSPC_XMLDOC_TRAILER) { /* * This is an empty element, which means we're pretty much * done. The next character should be the closing tag. Grab * it to make sure and then we're done. * * !!TWK 07/26/98 * had to add a fix here to handle having actual attributes * for the empty element. */ ospvErrCode = OSPPXMLDocReadChar(ospvBfrAddr, ospvEncoding, &readChar); if ( (ospvErrCode == OSPC_ERR_NO_ERROR) && (readChar != OSPC_XMLDOC_CLOSE) ) { /* !!TWK -- here is the actual fix.... * What I'm assuming is that since this is an empty element * that there will no children * * now I go and grab the attributes for this tag */ ospvErrCode = OSPPXMLDocGetAttrs(ospvBfrAddr, ospvEncoding, &attrList); if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocSkipPastChar(ospvBfrAddr, ospvEncoding, OSPC_XMLDOC_CLOSE); } /* ospvErrCode = OSPC_ERR_XML_BAD_TAG; */ } } else if (readChar == OSPC_XMLDOC_CLOSE) { /* * We have a non-empty element with real content. Get the * content (child elements and/or character data) now. */ ospvErrCode = OSPPXMLDocGetContent(ospvBfrAddr, ospvEncoding, &childList, &valBfr); /* * The content is collected, skip past the closing bracket of * the element's closing tag. Note that we're not verifying that * the closing tag name is the same as the opening tag name. * That's obviously required for strict XML well-formedness, * but we're being a bit more liberal. */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocSkipPastChar(ospvBfrAddr, ospvEncoding, OSPC_XMLDOC_CLOSE); } } else { /* * Oops! We got to the end of the element the * first non-whitespace character wasn't a trailing slash * or a closing tag. That's an XML error. */ ospvErrCode = OSPC_ERR_XML_BAD_TAG; } } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * Now that we've got all the pieces, put them together into * the element. */ elem = OSPPXMLElemNew((const char *)OSPPBfrLinearPtr(nameBfr), (const char *)OSPPBfrLinearPtr(valBfr)); if (elem != OSPC_OSNULL) { OSPPListMove(&elem->ospmXMLElemAttrs, &attrList); OSPPListMove(&elem->ospmXMLElemChild, &childList); } *ospvElemAddr = elem; } /* free the buffers we allocated */ if (nameBfr != OSPC_OSNULL) { OSPPBfrDelete(&nameBfr); } if (valBfr != OSPC_OSNULL) { OSPPBfrDelete(&valBfr); } /* and delete any lists that are still hanging around */ for ( elem = (OSPTXMLELEM *)OSPPListRemove(&childList); elem != OSPC_OSNULL; elem = (OSPTXMLELEM *)OSPPListRemove(&childList) ) { OSPPXMLElemDelete(&elem); } for ( attr = (OSPTXMLATTR *)OSPPListRemove(&attrList); attr != OSPC_OSNULL; attr = (OSPTXMLATTR *)OSPPListRemove(&attrList) ) { OSPPXMLAttrDelete(&attr); } return(ospvErrCode);}/**//*-----------------------------------------------------------------------* * OSPPXMLDocGetAttrs() - get the attributes for an element *-----------------------------------------------------------------------*/unsigned /* returns error code */OSPPXMLDocGetAttrs( OSPTBFR **ospvBfrAddr, /* buffer containing document */ OSPTXMLENC ospvEncoding, /* character encoding for the document */ OSPTLIST *ospvAttrs /* list for attributes */){ unsigned ospvErrCode = OSPC_ERR_NO_ERROR; unsigned char readChar = '\0'; OSPTXMLATTR *attr = OSPC_OSNULL; if (ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (*ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (ospvEncoding == ospeXMLEncUnknown) { ospvErrCode = OSPC_ERR_XML_BAD_ENC; } if (ospvAttrs == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ATTR; } /* go into a loop looking for attributes */ while (ospvErrCode == OSPC_ERR_NO_ERROR) { /* skip whitespace */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocSkipWhite(ospvBfrAddr, ospvEncoding); } /* take a peek at the next character to see if it's a name */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { OSPPXMLDocPeekCharN(ospvBfrAddr, ospvEncoding, 0, &readChar, (int *)&ospvErrCode); } if (ospvErrCode == OSPC_ERR_NO_ERROR) { if (!OSPPXMLIsName1(readChar)) { /* * Indeed, the next character isn't a valid name * beginning, so we're done. */ break; } /* we've got a valid name - get the whole attribute */ ospvErrCode = OSPPXMLDocGetAttr(ospvBfrAddr, ospvEncoding, &attr); /* if successful, add it to the list */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { OSPPListAppend(ospvAttrs, attr); } } } return(ospvErrCode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -