📄 ospxmlenc.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. * *******#########################################################################*#########################################################################*#########################################################################*//* * ospxmlenc.c - Generic XML document encoding functions. */#include "osp.h"#include "ospbfr.h"#include "osperrno.h"#include "ospxmlattr.h"#include "ospxmlelem.h"#include "ospxmltype.h"#include "ospxmldoc.h"/**//*-----------------------------------------------------------------------* * OSPPXMLDocCreate() - create a linear document from a root element *-----------------------------------------------------------------------*/int /* returns error code */OSPPXMLDocCreate( OSPTXMLELEM *ospvElem, /* root element for document */ OSPTBFR **ospvBfrAddr /* buffer in which to put doc */){ int ospvErrCode = OSPC_ERR_NO_ERROR; unsigned cnt = 0; if (ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (*ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } /* * First start off with the XML declaration. This is not technically * required by the XML specification since we're not doing anything * other than XML version 1.0, nor are we using any fancy character * encodings. */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { cnt = OSPPBfrWriteBlock(ospvBfrAddr, OSPC_XMLDOC_DECL, OSPC_XMLDOC_DECLLEN); if (cnt == OSPC_XMLDOC_DECLLEN) { /* * If the declaration was successfully added, go ahead and * construct the root element. */ ospvErrCode = OSPC_ERR_BUF_INCOMPLETE; ospvErrCode = OSPPXMLDocAddElem(ospvElem, ospvBfrAddr); /* re-add this code later (maybe) */ /* ospvErrCode = OSPPXMLDocAddElem(ospvElem, ospvBfrAddr); */ } else { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } return (ospvErrCode);}/**//*-----------------------------------------------------------------------* * OSPPXMLDocAddElem() - add an element to a document *-----------------------------------------------------------------------*/int /* returns error code */OSPPXMLDocAddElem( OSPTXMLELEM *ospvElem, /* element to add */ OSPTBFR **ospvBfrAddr /* buffer to add to */){ int ospvErrCode = OSPC_ERR_NO_ERROR; OSPTXMLELEM *child = OSPC_OSNULL; OSPTXMLATTR *attr = OSPC_OSNULL; const char *val = OSPC_OSNULL; unsigned vallen = 0; unsigned cnt; /* * Because of the length of this routine, it's broken up into the * eight major steps involved in encoding an element. Look for the * "**** STEP n:" comments that emphasize these steps. */ if (ospvElem == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_XML_NO_ELEMENT; } if (ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (*ospvBfrAddr == OSPC_OSNULL) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * Pre-calculate some useful variables; we might need them in several * places in the following code. We're pre-calculating the element * value, and the element value's length. */ val = OSPPXMLElemGetValue(ospvElem); if (val != OSPC_OSNULL) { vallen = OSPM_STRLEN(val); } else { vallen = 0; } } if (ospvErrCode == OSPC_ERR_NO_ERROR) { /**** STEP 1: begin with the opening bracket */ ospvErrCode = OSPPXMLDocAddChar(ospvBfrAddr, OSPC_XMLDOC_OPEN); } /**** STEP 2: add the element name */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocAddElemName(ospvElem, ospvBfrAddr); } /**** STEP 3: if no children or contents, add trailer */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * Empty elements have neither children or content; they * can, however, include attributes (so we don't bother to * check for attributes or not). */ child = (OSPTXMLELEM *)OSPPXMLElemFirstChild(ospvElem); if ((child == OSPC_OSNULL) && (vallen == 0)) { /* if the element is empty, go ahead and add the trailer */ ospvErrCode = OSPPXMLDocAddChar(ospvBfrAddr, OSPC_XMLDOC_TRAILER); } } /**** STEP 4: add the attributes */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* the "for" loop steps through each attribute */ for (attr = (OSPTXMLATTR *)OSPPXMLElemFirstAttr(ospvElem); ((attr != OSPC_OSNULL) && (ospvErrCode == OSPC_ERR_NO_ERROR)); attr = (OSPTXMLATTR *)OSPPXMLElemNextAttr(ospvElem, attr) ) { /* * Attributes are separated by spaces, and we add a space * first in order to separate the first attribute from the * element name. That also means that we won't end up with * any extra trailing space, which is correct. */ ospvErrCode = OSPPXMLDocAddChar(ospvBfrAddr, OSPC_XMLDOC_SPACE); /* now add the attributes themselves */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocAddAttr(attr, ospvBfrAddr); } } } /**** STEP 5: add the closing bracket (for the opening tag) */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { ospvErrCode = OSPPXMLDocAddChar(ospvBfrAddr, OSPC_XMLDOC_CLOSE); /* add newline for readability */ ospvErrCode = OSPPXMLDocAddChar(ospvBfrAddr, OSPC_XMLDOC_LF); } /**** STEP 6: add the child elements */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* the "for" loop walks through all child elements */ for (child = (OSPTXMLELEM *)OSPPXMLElemFirstChild(ospvElem); ((child != OSPC_OSNULL) && (ospvErrCode == OSPC_ERR_NO_ERROR)); child = (OSPTXMLELEM *)OSPPXMLElemNextChild(ospvElem, child) ) { /* * Call ourselves recursively. Since OSP documents aren't * terribly deep in structure, this shouldn't cause too * much grief with stack space, etc.. Still, there is a * possible optimization here. */ ospvErrCode = OSPPXMLDocAddElem(child, ospvBfrAddr ); } } /**** STEP 7: add the value itself */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* of course, make sure there's something to add */ if (vallen > 0) { cnt = OSPPBfrWriteBlock(ospvBfrAddr, (const void *)val, vallen); if (cnt != vallen) { ospvErrCode = OSPC_ERR_BUF_EMPTY; } } } /**** STEP 8: add the closing tag (but only if there was some content) */ if (ospvErrCode == OSPC_ERR_NO_ERROR) { /* * Empty elements have neither children or content; they * can, however, include attributes (so we don't bother to * check for attributes or not). */ child = (OSPTXMLELEM *)OSPPXMLElemFirstChild(ospvElem); if ((child != OSPC_OSNULL) || (vallen != 0)) { /* first is the opening bracket */ ospvErrCode = OSPPXMLDocAddChar(ospvBfrAddr, OSPC_XMLDOC_OPEN); /* then the trailing slash */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -