void XMLNode::serialiseR(const XMLNodeData *pEntry, TextWriter &writer, int nFormat) { unsigned cb; int nChildFormat = -1; bool bHasChildren = false; assert(pEntry); // If the element has no name then assume this is the head node. if (!string_is_empty(pEntry->lpszName)) { // "<elementname " cb = nFormat == -1 ? 0 : nFormat; write_indent(writer, cb); writer.write('<'); if (pEntry->isDeclaration) writer.write('?'); writer.write(pEntry->lpszName); // Enumerate attributes and add them to the string for (auto i = pEntry->pAttribute.begin(), end = pEntry->pAttribute.end(); i != end; ++i) { const XMLNodeData::Attribute *pAttr = &*i; writer.write(' '); writer.write(pAttr->lpszName); writer.write('='); writer.write('"'); if (pAttr->lpszValue != NULL) write_xml_string(writer, pAttr->lpszValue); writer.write('"'); pAttr++; } bHasChildren = pEntry->HasChildren(); if (pEntry->isDeclaration) { writer.write('?'); writer.write('>'); if (nFormat != -1) writer.newline(); } else // If there are child nodes we need to terminate the start tag if (bHasChildren) { writer.write('>'); if (nFormat != -1) writer.newline(); } } // Calculate the child format for when we recurse. This is used to // determine the number of spaces used for prefixes. if (nFormat != -1) { if (!string_is_empty(pEntry->lpszName)) nChildFormat = nFormat + 1; else nChildFormat = nFormat; } /* write the child elements */ for (auto i = pEntry->begin(), end = pEntry->end(); i != end; ++i) serialiseR(i->d, writer, nChildFormat); /* write the text */ if (!pEntry->text.empty()) { if (nFormat != -1) { write_indent(writer, nFormat + 1); write_xml_string(writer, pEntry->text.c_str()); writer.newline(); } else { write_xml_string(writer, pEntry->text.c_str()); } } if (!string_is_empty(pEntry->lpszName) && !pEntry->isDeclaration) { // If we have child entries we need to use long XML notation for // closing the element - "<elementname>blah blah blah</elementname>" if (bHasChildren) { // "</elementname>\0" if (nFormat != -1) write_indent(writer, nFormat); writer.write("</"); writer.write(pEntry->lpszName); writer.write('>'); } else { // If there are no children we can use shorthand XML notation - // "<elementname/>" // "/>\0" writer.write("/>"); } if (nFormat != -1) writer.newline(); } }