The class xml_io contains a descriptor list that represents structured data that can be encoded to or decoded from XML strings. Member functions to decode XML into this list, encode XML from this list are available, as well as functions to build up the list, or traverse the list to read the decoded data.
Each element in the descriptor list has a unique numeric ID.
The ID XML_ROOT_TAG (0xffff) represents the root element. It can contain no or a single element. Typically the root contains an object that holds all the data.
The following functions put an element into the XML structure. Note: The elements cannot be added in any sequence. An element is considered closed, when to its parent another element was added. Then you cannot add further elements to this.
Example:
word root = xml.add_tag(XML_ROOT_TAG,"root");
word base = xml.add_tag(root, "tag1");
xml.add_attribute(base, "attribute1")
xml.add_tag(root, "tag2");
// this does not work, because tag base is already closed
// by adding tag2 to its parent
xml.add_attribute(base, "attribute2");
Note: There is a size limitation for encoding, decoding XML. A maximum number of 4096 elements is supported. In this respect as element a tag, an attribute, an attribute value and a content value counts as element. So an XML <tag attribute="attribute-value"/> consists of 3 elements.
Parameters:
The following functions can be used for encoding.
Functions for decoding:
Elements can be accessed by name using the following functions.
Parameters:
To navigate in the element tree, the following functions are available
For a single XML data structure there is the above limitation of the maximum number of elements. Larger XML can be read, if they consist on some level of a list of sub structures which are limited in size. Such a XML can be decoded block by block. Decoding can be started with the first block. It will end with an incomplete XML. All sub tags which are complete, can be read. Then there are functions to remove all the complete blocks from the data, freeing space in the buffer, which can be filled with the next block and decoding can continue. For this the following functions are available:
Example:
class xml_io xml(buffer); // the xml_io class used for decoding
...
byte error = xml.read(); // decode the data copied to buffer
// do handling of all complete elements
...
if (error == XML_ERROR_INCOMPLETE) {
char b[XML_CHUNK_SIZE];
class xml_io save(b); // temporary xml_io to copy the data
// save the incomplete data to temporary xml_io base is the tag containing the
// tags of the limited size
xml.save_incomplete(base,step,save);
// in the temporary structure, navigate to the tag containing the tags of
// limited size. In this example it is test/steps
base = save.get_tag(0xffff,"test");
base = save.get_tag(base,"steps");
// get the handle of the first (incomplete) tag
step = save.get_first(XML_TYPE_TAG,base);
// copy back the saved XML to the original xml_io
save.save_incomplete(base,step,xml);
// restore base to test/steps and step to the first incomplete tag, so
// handling of the data can continue here
base = xml.get_tag(0xffff,"test");
base = xml.get_tag(base,"steps");
step = xml.get_first(XML_TYPE_TAG,base);
// get end of data in the buffer, to identify were new data has to be copied
// to
offset = xml.ofs();
}
// copy the data into the buffer, starting at offset. Make shure it is 0 terminated.
// after that handling of the next block can start with xml.read() again