This is part 4/14 of my Implementing IXmlWriter post series.
One of the enhancements that XML introduced over SGML was a shorthand for specifying an element with no content by adding a trailing slash at the end of an open element. For example, <br/> is equivalent to <br></br>. Let’s add this functionality to the previous version of IXmlWriter.
Here’s the test case:
1
2
3
4
5
6
7
8
StringXmlWriter xmlWriter;
xmlWriter.WriteStartElement("root");
xmlWriter.WriteStartElement("emptyElement");
xmlWriter.WriteEndElement();
xmlWriter.WriteEndElement();
std::string strXML = xmlWriter.GetXmlString();
// strXML should be <root><emptyElement/></root>
How does this affect our previous implementation?
We clearly cannot write the > character to close the start element in WriteStartElement().
WriteEndElement() needs to be able to detect if a still-opened start element was written and if so, to write the /> sequence. Otherwise, it needs to write the full end element string.
Because the > character will not be written in WriteStartElement(), we also need to worry about closing the start element in virtually every function.
The simplest way to implement this feature that I can think of is to keep an extra bool which remembers whether a unclosed start element has been written, and to handle this case in all relevant functions. Because we have all the previous test cases, I simply made the relevant changes to WriteStartElement() and then kept running the test cases, adding code as necessary to fix failures. I ended up with the following implementation:
Remember, although the bool-based approach may not be the most elegant nor the eventual long-term solution, the idea with test-driven development is to write the simplest code possible to pass the existing test cases. If future test cases show the need, I will freely change this implementation detail, as the growing test suite allows me to make changes with great confidence.