/*! * \brief Appends a string to a buffer, substituting some characters by escape * sequences. */ static void copy_with_escape( /*! [in,out] The input/output buffer. */ ixml_membuf *buf, /*! [in] The string to copy from. */ const char *p) { int i; int plen; if (p == NULL) { return; } plen = strlen( p ); for (i = 0; i < plen; i++) { switch (p[i]) { case '<': ixml_membuf_append_str(buf, "<"); break; case '>': ixml_membuf_append_str(buf, ">"); break; case '&': ixml_membuf_append_str(buf, "&"); break; case '\'': ixml_membuf_append_str(buf, "'"); break; case '\"': ixml_membuf_append_str(buf, """); break; default: ixml_membuf_append(buf, &p[i]); break; } } }
/*================================================================ * copy_with_escape * * *=================================================================*/ void copy_with_escape( INOUT ixml_membuf * buf, IN char *p ) { int i; int plen; if( p == NULL ) return; plen = strlen( p ); for( i = 0; i < plen; i++ ) { switch ( p[i] ) { case '<': ixml_membuf_append_str( buf, "<" ); break; case '>': ixml_membuf_append_str( buf, ">" ); break; case '&': ixml_membuf_append_str( buf, "&" ); break; case '\'': ixml_membuf_append_str( buf, "'" ); break; case '\"': ixml_membuf_append_str( buf, """ ); break; default: ixml_membuf_append( buf, &p[i] ); } } }
DOMString ixmlDocumenttoString(IXML_Document *doc) { IXML_Node* rootNode = (IXML_Node *)doc; ixml_membuf memBuf; ixml_membuf *buf = &memBuf; if(rootNode == NULL) { return NULL; } ixml_membuf_init(buf); ixml_membuf_append_str(buf, "<?xml version=\"1.0\"?>\r\n"); ixmlDomTreetoString(rootNode, buf); return buf->buf; }
/*================================================================ * ixmlPrintDomTreeRecursive * It is a recursive function to print all the node in a tree. * Internal to parser only. * *=================================================================*/ void ixmlPrintDomTreeRecursive( IN IXML_Node * nodeptr, IN ixml_membuf * buf ) { char *nodeName = NULL; char *nodeValue = NULL; IXML_Node *child = NULL, *sibling = NULL; if( nodeptr != NULL ) { nodeName = ( char * )ixmlNode_getNodeName( nodeptr ); nodeValue = ixmlNode_getNodeValue( nodeptr ); switch ( ixmlNode_getNodeType( nodeptr ) ) { case eTEXT_NODE: copy_with_escape( buf, nodeValue ); break; case eCDATA_SECTION_NODE: ixml_membuf_append_str( buf, nodeValue ); break; case ePROCESSING_INSTRUCTION_NODE: ixml_membuf_append_str( buf, "<?" ); ixml_membuf_append_str( buf, nodeName ); ixml_membuf_append_str( buf, " " ); ixml_membuf_append_str( buf, nodeValue ); ixml_membuf_append_str( buf, "?>\n" ); break; case eDOCUMENT_NODE: ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild ( nodeptr ), buf ); break; case eATTRIBUTE_NODE: ixml_membuf_append_str( buf, nodeName ); ixml_membuf_append_str( buf, "=\"" ); if( nodeValue != NULL ) { ixml_membuf_append_str( buf, nodeValue ); } ixml_membuf_append_str( buf, "\"" ); if( nodeptr->nextSibling != NULL ) { ixml_membuf_append_str( buf, " " ); ixmlPrintDomTreeRecursive( nodeptr->nextSibling, buf ); } break; case eELEMENT_NODE: ixml_membuf_append_str( buf, "<" ); ixml_membuf_append_str( buf, nodeName ); if( nodeptr->firstAttr != NULL ) { ixml_membuf_append_str( buf, " " ); ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf ); } child = ixmlNode_getFirstChild( nodeptr ); if( ( child != NULL ) && ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) { ixml_membuf_append_str( buf, ">\n" ); } else { ixml_membuf_append_str( buf, ">" ); } // output the children ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild ( nodeptr ), buf ); // Done with children. Output the end tag. ixml_membuf_append_str( buf, "</" ); ixml_membuf_append_str( buf, nodeName ); sibling = ixmlNode_getNextSibling( nodeptr ); if( sibling != NULL && ixmlNode_getNodeType( sibling ) == eTEXT_NODE ) { ixml_membuf_append_str( buf, ">" ); } else { ixml_membuf_append_str( buf, ">\n" ); } ixmlPrintDomTreeRecursive( ixmlNode_getNextSibling ( nodeptr ), buf ); break; default: break; } } }
/*================================================================ * ixmlDomTreetoString * Converts a DOM tree into a text string * Element, and Attribute nodes are handled differently. * We don't want to print the Element and Attribute nodes' sibling. * External function. * *=================================================================*/ void ixmlDomTreetoString( IN IXML_Node * nodeptr, IN ixml_membuf * buf ) { char *nodeName = NULL; char *nodeValue = NULL; IXML_Node *child = NULL; if( ( nodeptr == NULL ) || ( buf == NULL ) ) { return; } nodeName = ( char * )ixmlNode_getNodeName( nodeptr ); nodeValue = ixmlNode_getNodeValue( nodeptr ); switch ( ixmlNode_getNodeType( nodeptr ) ) { case eTEXT_NODE: case eCDATA_SECTION_NODE: case ePROCESSING_INSTRUCTION_NODE: case eDOCUMENT_NODE: ixmlPrintDomTreeRecursive( nodeptr, buf ); break; case eATTRIBUTE_NODE: ixml_membuf_append_str( buf, nodeName ); ixml_membuf_append_str( buf, "=\"" ); ixml_membuf_append_str( buf, nodeValue ); ixml_membuf_append_str( buf, "\"" ); break; case eELEMENT_NODE: ixml_membuf_append_str( buf, "<" ); ixml_membuf_append_str( buf, nodeName ); if( nodeptr->firstAttr != NULL ) { ixml_membuf_append_str( buf, " " ); ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf ); } child = ixmlNode_getFirstChild( nodeptr ); if( ( child != NULL ) && ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) { ixml_membuf_append_str( buf, ">" ); } else { ixml_membuf_append_str( buf, ">" ); } // output the children ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild( nodeptr ), buf ); // Done with children. Output the end tag. ixml_membuf_append_str( buf, "</" ); ixml_membuf_append_str( buf, nodeName ); ixml_membuf_append_str( buf, ">" ); break; default: break; } }
/*! * \brief Recursive function to print all the node in a tree. * Internal to parser only. */ static void ixmlPrintDomTreeRecursive( /*! [in] \todo documentation. */ IXML_Node *nodeptr, /*! [in] \todo documentation. */ ixml_membuf *buf) { const char *nodeName = NULL; const char *nodeValue = NULL; IXML_Node *child = NULL, *sibling = NULL; if (nodeptr != NULL) { nodeName = (const char *)ixmlNode_getNodeName(nodeptr); nodeValue = ixmlNode_getNodeValue(nodeptr); switch (ixmlNode_getNodeType(nodeptr)) { case eTEXT_NODE: copy_with_escape(buf, nodeValue); break; case eCDATA_SECTION_NODE: ixml_membuf_append_str(buf, "<![CDATA["); ixml_membuf_append_str(buf, nodeValue); ixml_membuf_append_str(buf, "]]>"); break; case ePROCESSING_INSTRUCTION_NODE: ixml_membuf_append_str(buf, "<?"); ixml_membuf_append_str(buf, nodeName); ixml_membuf_append_str(buf, " "); copy_with_escape(buf, nodeValue); ixml_membuf_append_str(buf, "?>\n"); break; case eDOCUMENT_NODE: ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild(nodeptr), buf); break; case eATTRIBUTE_NODE: ixml_membuf_append_str(buf, nodeName); ixml_membuf_append_str(buf, "=\""); copy_with_escape(buf, nodeValue); ixml_membuf_append_str(buf, "\""); if (nodeptr->nextSibling != NULL) { ixml_membuf_append_str(buf, " "); ixmlPrintDomTreeRecursive(nodeptr->nextSibling, buf); } break; case eELEMENT_NODE: ixml_membuf_append_str(buf, "<"); ixml_membuf_append_str(buf, nodeName); if (nodeptr->firstAttr != NULL) { ixml_membuf_append_str(buf, " "); ixmlPrintDomTreeRecursive(nodeptr->firstAttr, buf); } child = ixmlNode_getFirstChild(nodeptr); if (child != NULL && ixmlNode_getNodeType(child) == eELEMENT_NODE) { ixml_membuf_append_str(buf, ">\r\n"); } else { ixml_membuf_append_str(buf, ">"); } // output the children ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild(nodeptr), buf); // Done with children. Output the end tag. ixml_membuf_append_str(buf, "</"); ixml_membuf_append_str(buf, nodeName); sibling = ixmlNode_getNextSibling(nodeptr); if (sibling != NULL && ixmlNode_getNodeType(sibling) == eTEXT_NODE) { ixml_membuf_append_str( buf, ">" ); } else { ixml_membuf_append_str( buf, ">\r\n" ); } ixmlPrintDomTreeRecursive( ixmlNode_getNextSibling(nodeptr), buf); break; default: IxmlPrintf("(%s::ixmlPrintDomTreeRecursive) line %d: " "Warning, unknown node type %d\n", __FILE__, __LINE__, ixmlNode_getNodeType(nodeptr)); break; } } }