17

I have the following code:

class Program
{
    static void Main(string[] args)
    {
        using (var stream = File.Create(@"C:\test.xml"))
        {
            var xml =
                new XElement("root",
                    new XElement("subelement1", "1"),
                    new XElement("subelement2", "2"));

            var doc = new XDocument(xml);
            doc.Declaration = null;
            doc.Save(stream);
        }
    }
}

I am trying to get XML to save without the xml declaration, but even though I am nulling out the declaration of the XDocument, it is still being saved to the final XML.

This code is outputting:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <subelement1>1</subelement1>
  <subelement2>2</subelement2>
</root>
KallDrexx
  • 27,229
  • 33
  • 143
  • 254
  • Why do you wish to save an XML document without the declaration? It is useful to include a declaration which specifies the encoding and the version of the XML document for consumers of the XML file. – James Shuttler Jan 19 '12 at 13:40
  • Because this XML is being sent to some other in-company systems that apparently break if you have the xml declaration (and I have no control over those systems, it's another whole department) – KallDrexx Jan 19 '12 at 13:41
  • that's fair enough :) I just wondered why – James Shuttler Jan 19 '12 at 13:46

2 Answers2

17

Instead XDocument.Save() you can use XmlWriter with XmlWriterSettings.OmitXmlDeclaration set to true

using System.IO;
using System.Xml;
using System.Xml.Linq;

XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = true;

using (var stream = File.Create(@"C:\test.xml"))
using (XmlWriter xw = XmlWriter.Create(stream, xws))
{
    var xml = new XElement(
        "root",
        new XElement("subelement1", "1"),
        new XElement("subelement2", "2"));

    xml.Save(xw);
}
sll
  • 61,540
  • 22
  • 104
  • 156
9

You can do this using XmlWriter with a custom XmlWriterSettings (you'll need a using directive for System.Xml):

using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;

class Program
{
    static void Main(string[] args)
    {
        var xml =
            new XElement("root",
                         new XElement("subelement1", "1"),
                         new XElement("subelement2", "2"));

        var doc = new XDocument(xml);
        var settings = new XmlWriterSettings
        {
            OmitXmlDeclaration = true
        };
        using (var stream = File.Create(@"test.xml"))
        {
            using (var writer = XmlWriter.Create(stream, settings))
            {
                doc.Save(writer);
            }
        }
    }
}

That's assuming you want to specify the Stream - you can also create an XmlWriter from the filename:

using (var writer = XmlWriter.Create("test.xml", settings))
{
    doc.Save(writer);
}

(If you don't need the XDocument for anything else, you can just call Save on the root element, of course, in the same way.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    EDIT: if you DO NOT use Jon's code then it still adds the declaration as the `XDocument.Save` method calls the `XNode.GetXmlWriterSettings` method, which then returns a new `XmlWriterSettings` object, which has `OmitXmlDeclaration` set to false by default – James Shuttler Jan 19 '12 at 13:42
  • @JamesShuttler: The code above does *not* write the declaration for me. Did you try it and find that it did? – Jon Skeet Jan 19 '12 at 13:43
  • Why do you build the `XML` body in `XElement` and then insert it to `XDocument`. Instead of build the whole `XML` with `XDocument`? – gdoron Jan 19 '12 at 13:43
  • @gdoron: That's what the OP's code does. I've *only* changed the saving part. – Jon Skeet Jan 19 '12 at 13:44
  • 1
    @JonSkeet sorry I wasn't clear, your code doesn't write the XML declaration, that's correct. You said you weren't sure why it still added the declaration even though it had been explicitly removed in the poster's code. I was explaining why it is still added if you do not use the code that you have provided – James Shuttler Jan 19 '12 at 13:45
  • @JamesShuttler: Ah, right. That makes sense. Will just remove that bit to start with. – Jon Skeet Jan 19 '12 at 13:49
  • and for clarification, I only put it into the XDocument since that's where the `.Declaration` property resides, and I thought I would have to use an `XDocument` root to get the declaration not to show. – KallDrexx Jan 19 '12 at 14:09