Pages: [1]   Go Down
Author Topic: simple XMLwriter library for Arduino  (Read 1940 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Triggered by a post of Crossroads - http://forum.arduino.cc/index.php?topic=197251.0 - I wrote a simple library/class that helps to write XML output. Although still work in progress it seemed to me mature enough to post here so I can get feedback about all that is wrong.

Of course an example script to show how it can be used and its output.
Note that the data is made up or quite trivial.

Note the constructor can use any Print derived class, including Stream, Serial, etc (only tested Serial BTW).
XMLWriter XML(&Serial);

Code: (c++)
//
//    FILE: XMLWriterTest.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.01
// PURPOSE: make a simple XML generating lib
//    DATE: 2013-11-06
//     URL:
//
// Released to the public domain
//

#include <XMLWriter.h>

XMLWriter XML(&Serial);

char buffer[24];

void setup()
{
  Serial.begin(115200);

  XML.header();
  XML.comment("XMLWriterTest.ino\nThis is a demo of a simple XML lib for Arduino", true); // true means multi line here

  XML.tagOpen("Arduino", "42");

  XML.tagOpen("Ports");
  AnalogPorts("before");
  DigitalPorts();
  AnalogPorts("after");
  XML.tagClose();

  Weather();
  Weather2();

  XML.tagClose();
}

void Weather2()
{
  XML.comment("The weather in South Africa");
  for (int i=0; i<10; i++)
  {
    XML.tagStart("Weather");
    XML.tagField("Date", "20131106");
    XML.tagField("Time", "1:42");
    XML.tagField("Temp", "23.4");
    XML.tagField("Humi", "50%");
    XML.tagField("Rain", "10mm");
    XML.tagField("Sun", "40");
    XML.tagEnd();
  }
}

void Weather()
{
  XML.comment("The weather in Nebraska");
  XML.tagOpen("Weather");
  XML.writeNode("Date", "20131106");
  XML.writeNode("Time", "11:42");
  XML.writeNode("Temp", "23.4");
  XML.writeNode("Humi", "50%");
  XML.writeNode("Rain", "10mm");
  XML.writeNode("Sun", "40");
  XML.tagClose();
}

void AnalogPorts(char* name)
{
  XML.comment("The analog ports are multiplexed");
  XML.tagOpen("Analog", 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 float = 2
  XML.writeNode("Analog2", (5.0*analogRead(A2))/1023, 3);
  XML.tagClose();
}

void DigitalPorts()
{
  XML.comment("The digital ports are not multiplexed");
  XML.tagOpen("Digital");
  XML.writeNode("D1", itoa(digitalRead(1), buffer, 10));
  XML.writeNode("D13", digitalRead(13));
  XML.tagClose();
}

void loop()
{
}

The output looks as follows:
Code: (xml)
<?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>448</Analog0>
      <Analog1>362</Analog1>
      <Analog2>1.52</Analog2>
      <Analog2>1.584</Analog2>
    </Analog>

    <!-- The digital ports are not multiplexed -->
    <Digital>
      <D1>0</D1>
      <D13>0</D13>
    </Digital>

    <!-- The analog ports are multiplexed -->
    <Analog name="after">
      <Analog0>393</Analog0>
      <Analog1>428</Analog1>
      <Analog2>2.08</Analog2>
      <Analog2>1.994</Analog2>
    </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"/>
</Arduino>

Source see - https://github.com/RobTillaart/Arduino/tree/master/libraries/XMLWriter -

As always comments and remarks and improvements and ... are welcome.
(and no an XMLreader is not yet in the planning smiley-wink
« Last Edit: November 07, 2013, 02:15:23 pm by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice !

Library is at your github-site I suppose ?
Logged

SF Bay area
Offline Offline
Sr. Member
****
Karma: 2
Posts: 266
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How about adding check to escape the following characters

"   &quot;
'   &apos;
<   &lt;
>   &gt;
&   &amp;

or if not, to warn not to use those characters.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nice !

Library is at your github-site I suppose ?

yep I added the link in the first post.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How about adding check to escape the following characters

"   &quot;
'   &apos;
<   &lt;
>   &gt;
&   &amp;

or if not, to warn not to use those characters.
Good point, might make the footprint larger, added to TODO
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

handling escapes looks quit good
- need more testing
- refactor code
- performance?
Code: (code/output)
void testEscapes()
{
  XML.comment("Test escape chars");
  XML.tagOpen("char");
  XML.writeNode("quote", "\"hello\"");
  XML.writeNode("apos", "\'hello\'");
  XML.writeNode("less", "5 < 33");
  XML.writeNode("great", "Peter > John");
  XML.writeNode("amp", " &array[0] ");
  XML.tagClose();
}

==>

  <!-- Test escape chars -->
  <char>
    <quote>&quot;hello&quot;</quote>
    <apos>&apos;hello&apos;</apos>
    <less>5 &lt; 33</less>
    <great>Peter &gt; John</great>
    <amp> &amp;array[0] </amp>
  </char>

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

upgraded to 0.1.02 - https://github.com/RobTillaart/Arduino/tree/master/libraries/XMLWriter -

+ added setIndentSize(uint8_t n);   0 = no indent, 2 = default; 4 looks OK too (spaces, no tabs)
+ corrected history
+ added escape() for special chars. - tip doughboy
+ added comments in the form of 'example' output in .h file
+ added some #defines to make code more readable.

as always comments remarks welcome.
« Last Edit: November 09, 2013, 06:28:49 am by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello guys,
I am not an expert in programming in arduino but I would like to make a log as XML stored on an SD card.

This is why I come to you to find out which parameter set instead of (&Serial) on line 14.
Otherwise if you have other ideas to parse XML,I'm interested.
The aim being to insert tags into an existing XML.

Example:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Log>
<element id="1" year="2014" month="1" day="1" hour="00" min="00" sec="00">
<sensor id="T1">20.0</sensor>
<sensor id="T2">20.0</sensor>
<sensor id="T3">20.0</sensor>
<sensor id="T4">20.0</sensor>
</element>
</Log>
To :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Log>
<element id="1" year="2014" month="1" day="1" hour="00" min="00" sec="00">
<sensor id="T1">20.0</sensor>
<sensor id="T2">20.0</sensor>
<sensor id="T3">20.0</sensor>
<sensor id="T4">20.0</sensor>
</element>
<element id="2" year="2014" month="1" day="1" hour="00" min="01" sec="00">
<sensor id="T1">20.0</sensor>
<sensor id="T2">20.0</sensor>
<sensor id="T3">20.0</sensor>
<sensor id="T4">20.0</sensor>
</element>
</Log>
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
This is why I come to you to find out which parameter set instead of (&Serial) on line 14.
Should be something that implements the Print class,
The File Class is derived from the Stream Class which is derived from the Print class so that should work (to certain level)

The XML writer class does not support appending directly. What I would try is the following. Let your application go to the end of the of the file on SD card, do a reverse search for the last </log> entry and start writing from that point. MIght work or ... not smiley

Give it a try.


Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: