Search code examples
.netline-breaksxmldocument

Adding line breaks and indents to XmlDocument


What is the right way of adding line breaks and indents when building an XmlDocument to make its output (called by xmlDocoment->DocumentElement->OuterXml) look like this:

<QualifyingProperties Target="#SignatureElem_0" xmlns="http://uri.etsi.org/01903/v1.3.2#">
    <SignedProperties Id="SignedPropertiesElem_0">

This is the way I build my XmlDocument:

XmlDocument^ xmlDoc = gcnew XmlDocument();
xmlDoc->PreserveWhitespace = true;

XmlNode^ nQualifyingProperties = xmlDoc->CreateNode(XmlNodeType::Element, "QualifyingProperties", "http://uri.etsi.org/01903/v1.3.2#");
xmlDoc->AppendChild(nQualifyingProperties);
XmlNode^ nodAttribute = xmlDoc->CreateNode(XmlNodeType::Attribute, "Target", "");
nodAttribute->Value = SignatureId;
nQualifyingProperties->Attributes->SetNamedItem(nodAttribute)

XmlNode^ nSignedProperties = xmlDoc->CreateNode(XmlNodeType::Element, "SignedProperties", "http://uri.etsi.org/01903/v1.3.2#");
nQualifyingProperties->AppendChild(nSignedProperties);
nodAttribute = xmlDoc->CreateNode(XmlNodeType::Attribute, "Id", "");
nodAttribute->Value = SignedPropertiesId;
nSignedProperties->Attributes->SetNamedItem(nodAttribute);

I found that this works for line breaks:

XmlNode^ linebreak = xmlDoc->CreateTextNode("\n");
nQualifyingProperties->AppendChild(linebreak );

But I'm not sure it's the right way. Is it? And what about indents (tabs)?

EDIT: I am adding this XmlDocument to SignedXml as DataObject (where it's going to be signed), therefore I can't control formatting of this particular element, and while it's not a big deal, it would be nice to make it work the way I want it to work.


Solution

  • I have figured it out. XmlDocument should be written to a Stream with XmlWriter using, like Pavel suggested, XmlWriterSettings with Indent property enabled. Like this:

    XmlDocument^ xmlDocument = gcnew XmlDocument();
    xmlDocument->PreserveWhitespace = true;
    
    //add some elements
    
    XmlWriterSettings settings = new XmlWriterSettings();
    XmlWriterSettings.Indent = true;
    XmlWriterSettings.IndentChars = "\t"; //tabs instead of spaces
    
    Stream^ stream = gcnew MemoryStream(); //or FileStream to write an Xml file directly to disk
    
    XmlWriter^ writer = XmlWriter::Create(stream, settings);
    xmlDocument->WriteTo(writer);
    writer->Close();