+ added functions to manipulate layout more low level
+ added XMLWriterDemo01 to show these functions
+ added sample output (as comparison)
+ fixed small error
+ removed XMLWRITER_EXTENDED #ifdef
This commit is contained in:
rob tillaart 2016-04-27 14:14:37 +02:00
parent 85bc0eb4fa
commit d95660eecf
5 changed files with 183 additions and 26 deletions

View File

@ -1,7 +1,7 @@
//
// FILE: XMLWriter.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.05
// VERSION: 0.1.06
// DATE: 2013-11-06
// PURPOSE: Simple XML library
//
@ -12,6 +12,7 @@
// 0.1.03 - 2015-03-07 refactored - footprint + interface
// 0.1.04 - 2015-05-21 refactored - reduce RAM -> used F() macro etc.
// 0.1.05 - 2015-05-23 added XMLWRITER_MAXTAGSIZE 15 (to support KML coordinates tag)
// 0.1.06 - 2016-03-16 added incrIndent(), decrIndent(), indent(), raw();
//
// Released to the public domain
//
@ -39,7 +40,7 @@ void XMLWriter::header()
void XMLWriter::comment(char* text, bool multiLine)
{
_stream->println();
if (!multiLine) spaces();
if (!multiLine) indent();
_stream->print(F("<!-- "));
if (multiLine) _stream->println();
_stream->print(text);
@ -62,10 +63,10 @@ void XMLWriter::tagOpen(char* tag, char* name, bool newline)
_indent += _indentStep;
}
void XMLWriter::tagClose(bool indent)
void XMLWriter::tagClose(bool ind)
{
_indent -= _indentStep;
if (indent) spaces();
if (ind) indent();
_stream->print(F("</"));
_stream->print(tagStack[--_idx]);
_stream->println(F(">"));
@ -73,7 +74,7 @@ void XMLWriter::tagClose(bool indent)
void XMLWriter::tagStart(char *tag)
{
spaces();
indent();
_stream->print('<');
_stream->print(tag);
}
@ -114,7 +115,6 @@ void XMLWriter::setIndentSize(uint8_t size)
_indentStep = size;
}
#ifdef XMLWRITER_EXTENDED
void XMLWriter::tagField(char *field, uint8_t value, uint8_t base)
{
tagField(field, (uint32_t) value, base);
@ -185,7 +185,7 @@ void XMLWriter::writeNode(char* tag, uint16_t value, uint8_t base)
void XMLWriter::writeNode(char* tag, uint32_t value, uint8_t base)
{
tagOpen(tag, "", NONEWLINE);
_stream->print(value, base);
_stream->print(value, base); // todo: leading zero's
tagClose(NOINDENT);
}
@ -202,7 +202,7 @@ void XMLWriter::writeNode(char* tag, int16_t value, uint8_t base)
void XMLWriter::writeNode(char* tag, int32_t value, uint8_t base)
{
tagOpen(tag, "", NONEWLINE);
_stream->print(value, base);
_stream->print(value, base); // todo: leading zero's
tagClose(NOINDENT);
}
@ -219,15 +219,14 @@ void XMLWriter::writeNode(char* tag, double value, uint8_t decimals)
_stream->print(value, decimals);
tagClose(NOINDENT);
}
#endif
////////////////////////////////////////////////////////////////////
void XMLWriter::spaces()
void XMLWriter::indent()
{
for (uint8_t i=_indent; i>0; i--) _stream->print(' ');
}
////////////////////////////////////////////////////////////////////
#ifdef XMLWRITER_ESCAPE_SUPPORT
char c[6] = "\"\'<>&";
char expanded[][7] = { "&quot;", "&apos;","&lt;","&gt;","&amp;"}; // todo in flash

View File

@ -3,7 +3,7 @@
//
// FILE: XMLWriter.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.05
// VERSION: 0.1.06
// DATE: 2013-11-06
// PURPOSE: Simple XML writer library
//
@ -13,9 +13,10 @@
#include "Arduino.h"
// no pre 1.0 support!
#define XMLWRITER_VERSION "0.1.05"
#define XMLWRITER_VERSION "0.1.06"
// for comment()
#define NOMULTILINE false
#define MULTILINE true
// for tagOpen(), tagEnd()
@ -29,12 +30,10 @@
// deepness of XML tree 5..10
// needed for stack of tagStack
#define XMLWRITER_MAXLEVEL 5
#define XMLWRITER_MAXTAGSIZE 15
#define XMLWRITER_MAXLEVEL 5 // adjust for deeper nested structures
#define XMLWRITER_MAXTAGSIZE 15 // adjust for longer fields - !! eats memory !!
// reduce footprint by not using all
// possible datatypes
#define XMLWRITER_EXTENDED
// reduce footprint by commenting next line
#define XMLWRITER_ESCAPE_SUPPORT
class XMLWriter
@ -56,7 +55,7 @@ public:
// <tag name="name">
void tagOpen(char* tag, char* name, bool newline=true);
// </tag>
void tagClose(bool indent=true);
void tagClose(bool ind=true);
// <tag
void tagStart(char* tag);
@ -69,9 +68,14 @@ public:
void writeNode(char* tag, char* value);
// typically 0,2,4; default == 2;
void setIndentSize(uint8_t size);
void setIndentSize(uint8_t size = 2);
// for manual layout control
void incrIndent() { _indent += _indentStep; };
void decrIndent() { _indent -= _indentStep; };
void indent();
void raw(char * str) { _stream->print(str); }; // TODO Q:other types?
#ifdef XMLWRITER_EXTENDED
void tagField(char* field, uint8_t value, uint8_t base=DEC);
void tagField(char* field, uint16_t value, uint8_t base=DEC);
void tagField(char* field, uint32_t value, uint8_t base=DEC);
@ -89,8 +93,6 @@ public:
void writeNode(char* tag, int32_t value, uint8_t base=DEC);
void writeNode(char* tag, bool value);
void writeNode(char* tag, double value, uint8_t decimals=2);
#endif
#ifdef XMLWRITER_ESCAPE_SUPPORT
// expands the special xml chars
@ -102,7 +104,6 @@ private:
Print* _stream;
// for indentation
void spaces();
uint8_t _indent;
uint8_t _indentStep;

View File

@ -73,7 +73,7 @@ void AnalogPorts(char* name)
XML.writeNode("Analog0", itoa(analogRead(A0), buffer, 10));
XML.writeNode("Analog1", analogRead(A1));
XML.writeNode("Analog2", (5.0*analogRead(A2))/1023); // default nr decimals = 2
XML.writeNode("Analog2", (5.0*analogRead(A2))/1023, 3);
XML.writeNode("Analog3", (5.0*analogRead(A2))/1023, 3);
XML.tagClose();
}

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
XMLWriterTest.ino
This is a demo of a simple XML lib for Arduino
-->
<Arduino name="42">
<Ports>
<!-- The analog ports are multiplexed -->
<Analog name="before">
<Analog0>389</Analog0>
<Analog1>332</Analog1>
<Analog2>1.55</Analog2>
<Analog3>1.544</Analog3>
</Analog>
<!-- The digital ports are not multiplexed -->
<Digital>
<D1>0</D1>
<D13>1</D13>
</Digital>
<!-- The analog ports are multiplexed -->
<Analog name="after">
<Analog0>343</Analog0>
<Analog1>366</Analog1>
<Analog2>1.94</Analog2>
<Analog3>1.926</Analog3>
</Analog>
</Ports>
<!-- The weather in Nebraska -->
<Weather>
<Date>20131106</Date>
<Time>11:42</Time>
<Temp>23.4</Temp>
<Humi>50%</Humi>
<Rain>10mm</Rain>
<Sun>40</Sun>
</Weather>
<!-- The weather in South Africa -->
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<Weather Date="20131106" Time="1:42" Temp="23.4" Humi="50%" Rain="10mm" Sun="40"/>
<!-- Testing dataTypes I -->
<Datatypes>
<Bool>true</Bool>
<Bool>false</Bool>
<BIN>101010</BIN>
<DEC>42</DEC>
<HEX>2A</HEX>
<OCT>52</OCT>
</Datatypes>
<!-- Testing dataTypes II -->
<dataTypes Bool="true" Bool="false" BIN="101110111" DEC="375" HEX="177" OCT="567"/>
<dataTypes Bool="true" Bool="false" BIN="101010010" DEC="338" HEX="152" OCT="522"/>
<dataTypes Bool="true" Bool="false" BIN="101111010" DEC="378" HEX="17A" OCT="572"/>
</Arduino>

View File

@ -0,0 +1,88 @@
//
// FILE: XMLWriterDemo01.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: XML writer demo
// DATE: 2016-03-16
// URL:
//
// Released to the public domain
//
#include <XMLWriter.h>
XMLWriter XML(&Serial);
void setup()
{
Serial.begin(115200);
float p = random(100) * 1.0;
float y = random(100) * 1.0;
float r = random(100) * 1.0;
shoot(p, y, r);
}
void shoot(float p, float y, float r)
{
XML.header();
XML.comment("Demo opening tag with multiple fields");
XML.tagOpen("shoot");
XML.comment("use nodes for every field");
XML.tagOpen("position");
XML.writeNode("id", 0);
XML.writeNode("pitch", p);
XML.writeNode("yaw", y);
XML.writeNode("roll", r);
XML.writeNode("Date", "20160316");
XML.writeNode("Time", "101534");
XML.tagClose(); // position
XML.comment("use tagfields in tag");
XML.tagStart("position");
XML.tagField("id", 1);
XML.tagField("pitch", p);
XML.tagField("yaw", y);
XML.tagField("roll", r);
XML.tagField("Date", "20160316");
XML.tagField("Time", "101534");
XML.tagEnd();
XML.comment("use manual indent and raw output");
XML.tagStart("position");
XML.tagField("id", 2);
XML.tagField("pitch", p);
XML.tagField("yaw", y);
XML.tagField("roll", r);
XML.tagEnd(NEWLINE, NOSLASH);
XML.incrIndent();
XML.indent();
XML.raw("20160316\n");
XML.indent();
XML.raw("101534\n");
XML.decrIndent();
XML.tagStart("/position");
XML.tagEnd(NEWLINE, NOSLASH);
XML.comment("use manual indent + nodes");
XML.tagStart("position");
XML.tagField("id", 3);
XML.tagField("pitch", p);
XML.tagField("yaw", y);
XML.tagField("roll", r);
XML.tagEnd(NEWLINE, NOSLASH);
XML.incrIndent();
XML.writeNode("Date", "20160316");
XML.writeNode("Time", "101534");
XML.decrIndent();
XML.tagStart("/position");
XML.tagEnd(NEWLINE, NOSLASH);
XML.tagClose(); // shoot
}
void loop()
{
}