Mbed port of the Simple Plain Xml parser. See http://code.google.com/p/spxml/ for more details. This library uses less memory and is much better suited to streaming data than TinyXML (doesn\'t use as much C++ features, and especially works without streams). See http://mbed.org/users/hlipka/notebook/xml-parsing/ for usage examples.

Dependents:   spxmltest_weather VFD_fontx2_weather weather_LCD_display News_LCD_display ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spcanonxml.cpp Source File

spcanonxml.cpp

00001 /*
00002  * Copyright 2007 Stephen Liu
00003  * LGPL, see http://code.google.com/p/spxml/
00004  * For license terms, see the file COPYING along with this library.
00005  */
00006 
00007 #include <string.h>
00008 
00009 #include "spcanonxml.hpp"
00010 
00011 #include "spxmlnode.hpp"
00012 #include "spxmlutils.hpp"
00013 #include "spxmlcodec.hpp"
00014 
00015 SP_CanonXmlBuffer :: SP_CanonXmlBuffer( const SP_XmlNode * node )
00016 {
00017     mBuffer = new SP_XmlStringBuffer();
00018     dump( node, mBuffer );
00019 }
00020 
00021 SP_CanonXmlBuffer :: ~SP_CanonXmlBuffer()
00022 {
00023     if( NULL != mBuffer ) delete mBuffer;
00024     mBuffer = NULL;
00025 }
00026 
00027 const char * SP_CanonXmlBuffer :: getBuffer() const
00028 {
00029     return mBuffer->getBuffer();
00030 }
00031 
00032 int SP_CanonXmlBuffer :: getSize() const
00033 {
00034     return mBuffer->getSize();
00035 }
00036 
00037 void SP_CanonXmlBuffer :: canonEncode( const char * value,
00038         SP_XmlStringBuffer * buffer )
00039 {
00040     SP_XmlStringBuffer temp;
00041     SP_XmlStringCodec::encode( "", value, &temp );
00042 
00043     for( const char * pos = temp.getBuffer(); '\0' != *pos; pos++ ) {
00044         if( '\r' == *pos ) {
00045         } else if( '\n' == *pos ) {
00046             buffer->append( "&#10;" );
00047         } else {
00048             buffer->append( *pos );
00049         }
00050     }
00051 }
00052 
00053 void SP_CanonXmlBuffer :: dump(
00054         const SP_XmlNode * node, SP_XmlStringBuffer * buffer )
00055 {
00056     if( NULL == node ) return;
00057 
00058     if( SP_XmlNode::eXMLDOC == node->getType() ) {
00059         SP_XmlDocument * document = static_cast<SP_XmlDocument*>((SP_XmlNode*)node);
00060         const SP_XmlNodeList * children = document->getChildren();
00061         for( int j = 0; j < children->getLength(); j++ ) {
00062             dump( children->get( j ), buffer );
00063         }
00064     } else if( SP_XmlNode::eCDATA == node->getType() ) {
00065         SP_XmlCDataNode * cdata = static_cast<SP_XmlCDataNode*>((SP_XmlNode*)node);
00066 
00067         canonEncode( cdata->getText(), buffer );
00068     } else if( SP_XmlNode::ePI == node->getType() ) {
00069         SP_XmlPINode * piNode = static_cast<SP_XmlPINode*>((SP_XmlNode*)node);
00070 
00071         buffer->append( "<?" );
00072         buffer->append( piNode->getTarget() );
00073         if( '\0' != *( piNode->getTarget() ) ) buffer->append( ' ' );
00074         buffer->append( piNode->getData() );
00075         buffer->append( "?>" );
00076     } else if( SP_XmlNode::eCOMMENT == node->getType() ) {
00077         // ignore
00078     } else if( SP_XmlNode::eELEMENT == node->getType() ) {
00079         dumpElement( node, buffer );
00080     } else if( SP_XmlNode::eDOCDECL == node->getType() ) {
00081         // ignore
00082     } else if( SP_XmlNode::eDOCTYPE == node->getType() ) {
00083         // ignore
00084     } else {
00085         // ignore
00086     }
00087 }
00088 
00089 void SP_CanonXmlBuffer :: dumpElement(
00090         const SP_XmlNode * node, SP_XmlStringBuffer * buffer )
00091 {
00092     if( NULL == node ) return;
00093 
00094     if( SP_XmlNode::eELEMENT == node->getType() ) {
00095         SP_XmlElementNode * element = static_cast<SP_XmlElementNode*>((SP_XmlNode*)node);
00096         buffer->append( "<" );
00097         buffer->append( element->getName() );
00098 
00099         int i = 0;
00100 
00101         SP_XmlArrayList attrList;
00102         for( i = 0; i < element->getAttrCount(); i++ ) {
00103             attrList.append( (void*)element->getAttr( i, NULL ) );
00104         }
00105         attrList.sort( reinterpret_cast<int(*)(const void*, const void*)>(strcmp) );
00106 
00107         const char * name = NULL, * value = NULL;
00108         for( i = 0; i < attrList.getCount(); i++ ) {
00109             name = (char*)attrList.getItem( i );
00110             value = element->getAttrValue( name );
00111             if( NULL != name && NULL != value ) {
00112                 buffer->append( ' ' );
00113                 buffer->append( name );
00114                 buffer->append( "=\"" );
00115                 canonEncode( value, buffer );
00116                 buffer->append( "\"" );
00117             }
00118         }
00119 
00120         const SP_XmlNodeList * children = element->getChildren();
00121 
00122         buffer->append( ">" );
00123 
00124         for( int j = 0; j < children->getLength(); j++ ) {
00125             dump( children->get( j ), buffer );
00126         }
00127 
00128         buffer->append( "</" );
00129         buffer->append( element->getName() );
00130         buffer->append( ">" );
00131     } else {
00132         dump( node, buffer );
00133     }
00134 }
00135