Outline
Purpose
Provide a simple interface for writing formatted XML.
Classes
- See also
Description
The balxml::Formatter
class provides methods to write a formatted XML to an underlining output stream. These methods generate header, tags, data, attributes, comments in a human-readable, indented format.
XML documents use a self-describing and simple syntax that consists of nested XML elements. Each element is bounded by a pair of opening and closing tags. Within the pair of tags, there can be more nested elements, or just plain text or numeric data in text format. The opening tag of an element can also contain attributes in the form of name="value" pairs. This component provides methods to generate these XML ingredients and takes care of proper indentation and line wrapping. Visit http://www.w3schools.com/xml/xml_syntax.asp for a complete tutorial.
Special Characters
XML defines five special characters that must not appear text; instead these characters are must be represented by multi-byte escape sequences.
Special (Hex) XML Escape
Character Value Description Sequence
--------- ----- ----------- ----------
" x22 quote "
& x26 ampersand &
' x27 apostrophe '
< x3C less than <
> x3E greater than >
The following methods:
addAttribute
,
addData
, and
addListData
implicitly convert each special character found in string input to the appropriate escape sequence in the resulting XML document.
Valid Strings
Strings used to set element attributes and element data (see addAttribute
, addData
, and addListData
) must consist of (valid) UTF-8 byte sequences excepting certain control characters.
Control
Characters Description Allowed
----------- -------------------------- -------
x09 HT '\t' (horizontal tab) true
x0A LF '\n' (new line) true
x0D CR '\r' (carriage return) true
x7F DEL (delete) false
x01 .. 0x1F Other than HT, LF, and CR. false
Notice that range of 31 control characters between 0x01
and 0x1F
(inclusive) consist of three that are allowed and 28 that are not.
The detection of an invalid character in an input stream stops the transfer of data to the output stream. The output stream is put into a failed state.
Usage
This section illustrates intended use of this component.
Example 1: Basic Usage
This example shows ten steps of how to create an XML document using this component's major manipulators:
formatter.addHeader("UTF-8");
formatter.openElement("Fruits");
formatter.openElement("Oranges");
formatter.addAttribute("farm", "Francis' Orchard");
formatter.addAttribute("size", 3.5);
formatter.openElement("pickDate");
formatter.closeElement("pickDate");
formatter.addElementAndData("Quantity", 12);
formatter.closeElement("Oranges");
formatter.openElement("Apples");
formatter.addAttribute("farm", "Fuji & Sons");
formatter.addAttribute("size", 3);
formatter.closeElement("Apples");
formatter.closeElement("Fruits");
Definition bdlt_date.h:294
Indentation is correctly taken care of and the user need only concern themselves with the correct ordering of the XML elements they're trying to write. The output of the above example is:
+--bsl::cout--------------------------------------------------------------+
|<?xml version="1.0" encoding="UTF-8" ?> |
|<Fruits> |
| <Oranges farm="Francis' Orchard" size="3.5"> |
| <pickDate>2004-08-31</pickDate> |
| <Quantity>12</Quantity> |
| </Oranges> |
| <Apples farm="Fuji & Sons" size="3"/> |
|</Fruits> |
+-------------------------------------------------------------------------+
Following is a more complete usage example that uses most of the manipulators provided by balxml::Formatter:
formatter.addHeader("UTF-8");
formatter.openElement("Fruits");
formatter.openElement("Oranges");
formatter.addAttribute("farm", "Francis' Orchard");
formatter.addAttribute("size", 3.5);
formatter.addElementAndData("Quantity", 12);
formatter.openElement("pickDate");
formatter.closeElement("pickDate");
formatter.openElement("Feature");
formatter.addAttribute("shape", "round");
formatter.closeElement("Feature");
formatter.addComment("No wrapping for long comments");
formatter.closeElement("Oranges");
formatter.addBlankLine();
formatter.openElement("Apples");
formatter.addAttribute("farm", "Fuji & Sons");
formatter.addAttribute("size", 3);
formatter.openElement("pickDates",
formatter.closeElement("pickDates");
formatter.openElement("Feature");
formatter.addAttribute("color", "red");
formatter.addAttribute("taste", "juicy");
formatter.closeElement("Feature");
formatter.closeElement("Apples");
formatter.closeElement("Fruits");
formatter.reset();
formatter.addHeader();
formatter.openElement("Grains");
bsl::ostream& os = formatter.rawOutputStream();
os << "<free>anything that can mess up the XML doc</free>";
formatter.addData("Corn, Wheat, Oat");
formatter.closeElement("Grains");
Following are the two resulting documents, as separated by the call to reset(),
+--bsl::cout-----------------------------+
|<?xml version="1.0" encoding="UTF-8" ?> |
|<Fruits> |
| <Oranges |
| farm="Francis' Orchard" |
| size="3.5"> |
| <Quantity>12</Quantity> |
| <pickDate>2004-08-31</pickDate> |
| <Feature shape="round"/> |
| <!-- No wrapping for long comments --> |
| </Oranges> |
| |
| <Apples farm="Fuji & Sons" |
| size="3"> |
| <pickDates> |
| 2005-01-17 2005-02-21 |
| 2005-03-25 2005-05-30 |
| 2005-07-04 2005-09-05 |
| 2005-11-24 2005-12-25 |
| </pickDates> |
| <Feature color="red" |
| taste="juicy"/> |
| </Apples> |
|</Fruits> |
+----------------------------------------+
+--bsl::cout-----------------------------+
|<?xml version="1.0" encoding="UTF-8" ?> |
|<Grains><free>anything that can mess up the XML doc</free>
| Corn, Wheat, Oat</Grains> |
+----------------------------------------+