tags:

views:

430

answers:

5

I have an XDocument object and the ToString() method returns XML without any indentation. How do I create a string from this containing indented XML?

edit: I'm asking how to create an in memory string rather than writing out to a file.

edit: Looks like I accidentally asked a trick question here... ToString() does return indented XML.

+5  A: 

From here

XmlDocument doc = new XmlDocument();
doc.LoadXml("<item><name>wrench</name></item>");

// Save the document to a file and auto-indent the output.
XmlTextWriter writer = new XmlTextWriter("data.xml",null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);
tomfanning
The question is how to create a string, not how to create a file.
JC
@JC: Use a StringWriter instead of the file name in the XmlTextWriter's constructor to get a string.
Anna Lear
-1: Do not use `new XmlTextWriter()` or `new XmlTextReader()` past .NET 1.1. Use `XmlWriter.Create()` or `XmlReader.Create()`.
John Saunders
-1: The question is about XDocument, not XmlDocument.
Joel Mueller
A: 

To create a string using an XDocument (rather than an XmlDocument), you can use:

        XDocument doc = new XDocument(
            new XComment("This is a comment"),
            new XElement("Root",
                new XElement("Child1", "data1"),
                new XElement("Child2", "data2")
            )
        );

        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        StringBuilder sb = new StringBuilder();
        XmlWriter writer = XmlextWriter.Create(sb, settings);
        doc.WriteTo(writer);
        writer.Flush();
        string outputXml = sb.ToString();

Edit: Updated to use XmlWriter.Create and a StringBuilder.

DocMax
-1: Do not use new XmlTextWriter() or new XmlTextReader() past .NET 1.1. Use XmlWriter.Create() or XmlReader.Create()
John Saunders
Thanks, I'd missed that. I updated the sample accordingly (and reduced complexity with a StringBuilder at the same time!)
DocMax
A: 

OK, this will work...

static void Main(string[] args)
{
    Console.WriteLine(indentedXml());
}

static string indentedXml()
{
    XmlDocument doc = new XmlDocument();
    doc.LoadXml("<item><name>wrench</name></item>");

    using (MemoryStream ms = new MemoryStream())
    using (XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8))
    using (StreamReader sr = new StreamReader(ms))
    {
        writer.Formatting = Formatting.Indented;
        doc.Save(writer);
        ms.Position = 0;

        return sr.ReadToEnd();
    }
}

Feels like a large hammer to crack a small problem though. Must be a better way.

tomfanning
-1: Do not use new XmlTextWriter() or new XmlTextReader() past .NET 1.1. Use XmlWriter.Create() or XmlReader.Create()
John Saunders
-1: The question is about XDocument, not XmlDocument
Joel Mueller
+2  A: 

Just one more flavor of the same soup... ;-)

StringWriter sw = new StringWriter();
XmlTextWriter xw = new XmlTextWriter(sw);
xw.Formatting = Formatting.Indented;
doc.WriteTo(xw);
Console.WriteLine(sw.ToString());

Edit: thanks to John Saunders. Here is a version that should better conform to Creating XML Writers on MSDN.

using System;
using System.Text;
using System.Xml;
using System.Xml.Linq;

class Program
{
    static void Main(string[] args)
    {
        XDocument doc = new XDocument(
        new XComment("This is a comment"),
        new XElement("Root",
            new XElement("Child1", "data1"),
            new XElement("Child2", "data2")
            )
            );

        var builder = new StringBuilder();
        var settings = new XmlWriterSettings()
        {
            Indent = true
        };
        using (var writer = XmlWriter.Create(builder, settings))
        {
            doc.WriteTo(writer);
        }
        Console.WriteLine(builder.ToString());
    }
}
Fabrizio C.
Prefer this to mine, but where's your usings?!
tomfanning
-1: Do not use new XmlTextWriter() or new XmlTextReader() past .NET 1.1. Use XmlWriter.Create() or XmlReader.Create()
John Saunders
+4  A: 
XDocument doc = XDocument.Parse(xmlString);
string indented = doc.ToString();
John Saunders
This works fine. `XDocument.ToString()` formats with indentation by default. To get unformatted output, you have to go out of your way by calling `.ToString(SaveOptions.DisableFormatting)`
Joel Mueller