// Format an Xml element to be written to the config file.
// Params:
// xmlElement - the element
// linePosition - start position of the element
// indent - indent for each depth
// skipFirstIndent - skip indent for the first element?
//
static internal string FormatXmlElement(string xmlElement, int linePosition, int indent, bool skipFirstIndent) {
XmlParserContext context = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.Unicode);
XmlTextReader reader = new XmlTextReader(xmlElement, XmlNodeType.Element, context);
StringWriter stringWriter = new StringWriter(new StringBuilder(64), CultureInfo.InvariantCulture);
XmlUtilWriter utilWriter = new XmlUtilWriter(stringWriter, false);
// append newline before indent?
bool newLine = false;
// last node visited was text?
bool lastWasText = false;
// width of line from end of indentation
int lineWidth;
// length of the stringbuilder after last indent with newline
int sbLengthLastNewLine = 0;
while (reader.Read()) {
XmlNodeType nodeType = reader.NodeType;
if (lastWasText) {
utilWriter.Flush();
lineWidth = sbLengthLastNewLine - ((StringWriter)utilWriter.Writer).GetStringBuilder().Length;
}
else {
lineWidth = 0;
}
switch (nodeType) {
case XmlNodeType.CDATA:
case XmlNodeType.Element:
case XmlNodeType.EndElement:
case XmlNodeType.Comment:
// Do not indent if the last node was text - doing so would add whitespace
// that is included as part of the text.
if (!skipFirstIndent && !lastWasText) {
utilWriter.AppendIndent(linePosition, indent, reader.Depth, newLine);
if (newLine) {
utilWriter.Flush();
sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length;
}
}
break;
default:
break;
}
lastWasText = false;
switch (nodeType) {
case XmlNodeType.Whitespace:
break;
case XmlNodeType.SignificantWhitespace:
utilWriter.Write(reader.Value);
break;
case XmlNodeType.CDATA:
utilWriter.AppendCData(reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
utilWriter.AppendProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
utilWriter.AppendComment(reader.Value);
break;
case XmlNodeType.Text:
utilWriter.AppendEscapeTextString(reader.Value);
lastWasText = true;
break;
case XmlNodeType.Element:
{
// Write "<elem"
utilWriter.Write('<');
utilWriter.Write(reader.Name);
lineWidth += reader.Name.Length + 2;
int c = reader.AttributeCount;
for (int i = 0; i < c; i++) {
// Add new line if we've exceeded the line width
bool writeSpace;
if (lineWidth > MAX_LINE_WIDTH) {
utilWriter.AppendIndent(linePosition, indent, reader.Depth - 1, true);
lineWidth = indent;
writeSpace = false;
utilWriter.Flush();
sbLengthLastNewLine = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length;
}
else {
writeSpace = true;
}
// Write the attribute
reader.MoveToNextAttribute();
utilWriter.Flush();
int startLength = ((StringWriter)utilWriter.Writer).GetStringBuilder().Length;
if (writeSpace) {
utilWriter.AppendSpace();
}
utilWriter.Write(reader.Name);
utilWriter.Write('=');
utilWriter.AppendAttributeValue(reader);
utilWriter.Flush();
lineWidth += ((StringWriter)utilWriter.Writer).GetStringBuilder().Length - startLength;
}
}
// position reader back on element
reader.MoveToElement();
// write closing tag
if (reader.IsEmptyElement) {
utilWriter.Write(" />");
}
else {
utilWriter.Write('>');
}
break;
case XmlNodeType.EndElement:
utilWriter.Write("</");
utilWriter.Write(reader.Name);
utilWriter.Write('>');
break;
case XmlNodeType.EntityReference:
utilWriter.AppendEntityRef(reader.Name);
break;
// Ignore <?xml and <!DOCTYPE nodes
case XmlNodeType.XmlDeclaration:
case XmlNodeType.DocumentType:
default:
break;
}
// put each new element on a new line
newLine = true;
// do not skip any more indents
skipFirstIndent = false;
}
utilWriter.Flush();
string s = ((StringWriter)utilWriter.Writer).ToString();
return s;
}