Published: 2005-10-07
This is part 3/14 of my Implementing IXmlWriter post series.
Today’s addition to the previous iteration of IXmlWriter is quite trivial: supporting the WriteElementString() method.
Here’s the test case:
StringXmlWriter xmlWriter;
xmlWriter.WriteStartElement("root");
xmlWriter.WriteElementString("element", "value");
xmlWriter.WriteEndElement();
std::string strXML = xmlWriter.GetXmlString();
// strXML should be <root><element>value</element></root>
Implementation is extremely simple because WriteElementString() is nothing but a convenience method which calls WriteStartElement(), WriteString(), and WriteEndElement(). Therefore, here’s the new StringXmlWriter:
class StringXmlWriter
{
private:
std::stack<std::string> m_openedElements;
std::string m_xmlStr;
public:
void WriteStartElement(const std::string& localName)
{
m_openedElements.push(localName);
m_xmlStr += '<';
m_xmlStr += localName;
m_xmlStr += '>';
}
void WriteEndElement()
{
std::string lastOpenedElement = m_openedElements.top();
m_xmlStr += "</";
m_xmlStr += lastOpenedElement;
m_xmlStr += '>';
m_openedElements.pop();
}
void WriteString(const std::string& value)
{
typedef std::string::const_iterator iter_t;
for (iter_t iter = value.begin(); iter != value.end(); ++iter) {
if (*iter == '&') {
m_xmlStr += "&";
} else if (*iter == '<') {
m_xmlStr += "<";
} else if (*iter == '>') {
m_xmlStr += ">";
} else {
m_xmlStr += *iter;
}
}
}
void WriteElementString(const std::string& localName,
const std::string& value)
{
WriteStartElement(localName);
WriteString(value);
WriteEndElement();
}
std::string GetXmlString() const
{
return m_xmlStr;
}
};