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

Committer:
hlipka
Date:
Wed Nov 24 20:52:14 2010 +0000
Revision:
0:3fa97f2c0505
initial revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hlipka 0:3fa97f2c0505 1 /*
hlipka 0:3fa97f2c0505 2 * Copyright 2007 Stephen Liu
hlipka 0:3fa97f2c0505 3 * LGPL, see http://code.google.com/p/spxml/
hlipka 0:3fa97f2c0505 4 * For license terms, see the file COPYING along with this library.
hlipka 0:3fa97f2c0505 5 */
hlipka 0:3fa97f2c0505 6
hlipka 0:3fa97f2c0505 7 #include <string.h>
hlipka 0:3fa97f2c0505 8
hlipka 0:3fa97f2c0505 9 #include "spcanonxml.hpp"
hlipka 0:3fa97f2c0505 10
hlipka 0:3fa97f2c0505 11 #include "spxmlnode.hpp"
hlipka 0:3fa97f2c0505 12 #include "spxmlutils.hpp"
hlipka 0:3fa97f2c0505 13 #include "spxmlcodec.hpp"
hlipka 0:3fa97f2c0505 14
hlipka 0:3fa97f2c0505 15 SP_CanonXmlBuffer :: SP_CanonXmlBuffer( const SP_XmlNode * node )
hlipka 0:3fa97f2c0505 16 {
hlipka 0:3fa97f2c0505 17 mBuffer = new SP_XmlStringBuffer();
hlipka 0:3fa97f2c0505 18 dump( node, mBuffer );
hlipka 0:3fa97f2c0505 19 }
hlipka 0:3fa97f2c0505 20
hlipka 0:3fa97f2c0505 21 SP_CanonXmlBuffer :: ~SP_CanonXmlBuffer()
hlipka 0:3fa97f2c0505 22 {
hlipka 0:3fa97f2c0505 23 if( NULL != mBuffer ) delete mBuffer;
hlipka 0:3fa97f2c0505 24 mBuffer = NULL;
hlipka 0:3fa97f2c0505 25 }
hlipka 0:3fa97f2c0505 26
hlipka 0:3fa97f2c0505 27 const char * SP_CanonXmlBuffer :: getBuffer() const
hlipka 0:3fa97f2c0505 28 {
hlipka 0:3fa97f2c0505 29 return mBuffer->getBuffer();
hlipka 0:3fa97f2c0505 30 }
hlipka 0:3fa97f2c0505 31
hlipka 0:3fa97f2c0505 32 int SP_CanonXmlBuffer :: getSize() const
hlipka 0:3fa97f2c0505 33 {
hlipka 0:3fa97f2c0505 34 return mBuffer->getSize();
hlipka 0:3fa97f2c0505 35 }
hlipka 0:3fa97f2c0505 36
hlipka 0:3fa97f2c0505 37 void SP_CanonXmlBuffer :: canonEncode( const char * value,
hlipka 0:3fa97f2c0505 38 SP_XmlStringBuffer * buffer )
hlipka 0:3fa97f2c0505 39 {
hlipka 0:3fa97f2c0505 40 SP_XmlStringBuffer temp;
hlipka 0:3fa97f2c0505 41 SP_XmlStringCodec::encode( "", value, &temp );
hlipka 0:3fa97f2c0505 42
hlipka 0:3fa97f2c0505 43 for( const char * pos = temp.getBuffer(); '\0' != *pos; pos++ ) {
hlipka 0:3fa97f2c0505 44 if( '\r' == *pos ) {
hlipka 0:3fa97f2c0505 45 } else if( '\n' == *pos ) {
hlipka 0:3fa97f2c0505 46 buffer->append( "&#10;" );
hlipka 0:3fa97f2c0505 47 } else {
hlipka 0:3fa97f2c0505 48 buffer->append( *pos );
hlipka 0:3fa97f2c0505 49 }
hlipka 0:3fa97f2c0505 50 }
hlipka 0:3fa97f2c0505 51 }
hlipka 0:3fa97f2c0505 52
hlipka 0:3fa97f2c0505 53 void SP_CanonXmlBuffer :: dump(
hlipka 0:3fa97f2c0505 54 const SP_XmlNode * node, SP_XmlStringBuffer * buffer )
hlipka 0:3fa97f2c0505 55 {
hlipka 0:3fa97f2c0505 56 if( NULL == node ) return;
hlipka 0:3fa97f2c0505 57
hlipka 0:3fa97f2c0505 58 if( SP_XmlNode::eXMLDOC == node->getType() ) {
hlipka 0:3fa97f2c0505 59 SP_XmlDocument * document = static_cast<SP_XmlDocument*>((SP_XmlNode*)node);
hlipka 0:3fa97f2c0505 60 const SP_XmlNodeList * children = document->getChildren();
hlipka 0:3fa97f2c0505 61 for( int j = 0; j < children->getLength(); j++ ) {
hlipka 0:3fa97f2c0505 62 dump( children->get( j ), buffer );
hlipka 0:3fa97f2c0505 63 }
hlipka 0:3fa97f2c0505 64 } else if( SP_XmlNode::eCDATA == node->getType() ) {
hlipka 0:3fa97f2c0505 65 SP_XmlCDataNode * cdata = static_cast<SP_XmlCDataNode*>((SP_XmlNode*)node);
hlipka 0:3fa97f2c0505 66
hlipka 0:3fa97f2c0505 67 canonEncode( cdata->getText(), buffer );
hlipka 0:3fa97f2c0505 68 } else if( SP_XmlNode::ePI == node->getType() ) {
hlipka 0:3fa97f2c0505 69 SP_XmlPINode * piNode = static_cast<SP_XmlPINode*>((SP_XmlNode*)node);
hlipka 0:3fa97f2c0505 70
hlipka 0:3fa97f2c0505 71 buffer->append( "<?" );
hlipka 0:3fa97f2c0505 72 buffer->append( piNode->getTarget() );
hlipka 0:3fa97f2c0505 73 if( '\0' != *( piNode->getTarget() ) ) buffer->append( ' ' );
hlipka 0:3fa97f2c0505 74 buffer->append( piNode->getData() );
hlipka 0:3fa97f2c0505 75 buffer->append( "?>" );
hlipka 0:3fa97f2c0505 76 } else if( SP_XmlNode::eCOMMENT == node->getType() ) {
hlipka 0:3fa97f2c0505 77 // ignore
hlipka 0:3fa97f2c0505 78 } else if( SP_XmlNode::eELEMENT == node->getType() ) {
hlipka 0:3fa97f2c0505 79 dumpElement( node, buffer );
hlipka 0:3fa97f2c0505 80 } else if( SP_XmlNode::eDOCDECL == node->getType() ) {
hlipka 0:3fa97f2c0505 81 // ignore
hlipka 0:3fa97f2c0505 82 } else if( SP_XmlNode::eDOCTYPE == node->getType() ) {
hlipka 0:3fa97f2c0505 83 // ignore
hlipka 0:3fa97f2c0505 84 } else {
hlipka 0:3fa97f2c0505 85 // ignore
hlipka 0:3fa97f2c0505 86 }
hlipka 0:3fa97f2c0505 87 }
hlipka 0:3fa97f2c0505 88
hlipka 0:3fa97f2c0505 89 void SP_CanonXmlBuffer :: dumpElement(
hlipka 0:3fa97f2c0505 90 const SP_XmlNode * node, SP_XmlStringBuffer * buffer )
hlipka 0:3fa97f2c0505 91 {
hlipka 0:3fa97f2c0505 92 if( NULL == node ) return;
hlipka 0:3fa97f2c0505 93
hlipka 0:3fa97f2c0505 94 if( SP_XmlNode::eELEMENT == node->getType() ) {
hlipka 0:3fa97f2c0505 95 SP_XmlElementNode * element = static_cast<SP_XmlElementNode*>((SP_XmlNode*)node);
hlipka 0:3fa97f2c0505 96 buffer->append( "<" );
hlipka 0:3fa97f2c0505 97 buffer->append( element->getName() );
hlipka 0:3fa97f2c0505 98
hlipka 0:3fa97f2c0505 99 int i = 0;
hlipka 0:3fa97f2c0505 100
hlipka 0:3fa97f2c0505 101 SP_XmlArrayList attrList;
hlipka 0:3fa97f2c0505 102 for( i = 0; i < element->getAttrCount(); i++ ) {
hlipka 0:3fa97f2c0505 103 attrList.append( (void*)element->getAttr( i, NULL ) );
hlipka 0:3fa97f2c0505 104 }
hlipka 0:3fa97f2c0505 105 attrList.sort( reinterpret_cast<int(*)(const void*, const void*)>(strcmp) );
hlipka 0:3fa97f2c0505 106
hlipka 0:3fa97f2c0505 107 const char * name = NULL, * value = NULL;
hlipka 0:3fa97f2c0505 108 for( i = 0; i < attrList.getCount(); i++ ) {
hlipka 0:3fa97f2c0505 109 name = (char*)attrList.getItem( i );
hlipka 0:3fa97f2c0505 110 value = element->getAttrValue( name );
hlipka 0:3fa97f2c0505 111 if( NULL != name && NULL != value ) {
hlipka 0:3fa97f2c0505 112 buffer->append( ' ' );
hlipka 0:3fa97f2c0505 113 buffer->append( name );
hlipka 0:3fa97f2c0505 114 buffer->append( "=\"" );
hlipka 0:3fa97f2c0505 115 canonEncode( value, buffer );
hlipka 0:3fa97f2c0505 116 buffer->append( "\"" );
hlipka 0:3fa97f2c0505 117 }
hlipka 0:3fa97f2c0505 118 }
hlipka 0:3fa97f2c0505 119
hlipka 0:3fa97f2c0505 120 const SP_XmlNodeList * children = element->getChildren();
hlipka 0:3fa97f2c0505 121
hlipka 0:3fa97f2c0505 122 buffer->append( ">" );
hlipka 0:3fa97f2c0505 123
hlipka 0:3fa97f2c0505 124 for( int j = 0; j < children->getLength(); j++ ) {
hlipka 0:3fa97f2c0505 125 dump( children->get( j ), buffer );
hlipka 0:3fa97f2c0505 126 }
hlipka 0:3fa97f2c0505 127
hlipka 0:3fa97f2c0505 128 buffer->append( "</" );
hlipka 0:3fa97f2c0505 129 buffer->append( element->getName() );
hlipka 0:3fa97f2c0505 130 buffer->append( ">" );
hlipka 0:3fa97f2c0505 131 } else {
hlipka 0:3fa97f2c0505 132 dump( node, buffer );
hlipka 0:3fa97f2c0505 133 }
hlipka 0:3fa97f2c0505 134 }
hlipka 0:3fa97f2c0505 135