1

I try to create the below line above all of the files by using System.Xml.Linq

<?xml version="1.0" encoding="utf-8"?>

and here is the code

 var firstLine = new XElement(
            "?xml", 
            new XAttribute("version", "1.0"), 
            new XAttribute("encoding", "UTF-8"),
            "?");

but after the run, I get the below error

result Message: System.Xml.XmlException: Name cannot begin with the '?' character, hexadecimal value 0x3F.

I wonder if anyone knows how I can solve this?

ShrnPrmshr
  • 353
  • 2
  • 5
  • 17

2 Answers2

3

That's an XML Declaration, represented by the XDeclaration type:

An example, from this doc:

XDocument doc = new XDocument(  
    new XDeclaration("1.0", "utf-8", "yes"),  
    new XElement("Root", "content")  
);  

Note that XDocument.ToString() will omit the declaration. Use XDocument.Save, e.g.:

using (var writer = new StringWriter())
{
    doc.Save(writer);
    Console.WriteLine(writer.ToString());
}

Note however that you'll get encoding="utf-16" in this case, because strings in .NET are UTF-16. If you want to serialize the XDocument to a UTF-8 byte array, then e.g.:

using (var stream = new MemoryStream())
{
    using (var writer = new StreamWriter(stream, Encoding.UTF8))
    {
        doc.Save(writer);
    }
    var utf8ByteArray = stream.ToArray();
    Console.WriteLine(Encoding.UTF8.GetString(utf8ByteArray));
}
canton7
  • 37,633
  • 3
  • 64
  • 77
  • thanks for your quick response! I can see that it has been added. but I wonder why after adding a XElemnt to this XDocument does not contain that line anymore!!! – ShrnPrmshr Nov 09 '20 at 09:34
  • @ShrnPrmshr Yes, `ToString()` omits the declaration, [see here](https://stackoverflow.com/questions/1228976/xdocument-tostring-drops-xml-encoding-tag) and [here](https://www.google.com/search?q=xdocument+tostring+declaration). Use `XDocument.Save`. See my edit – canton7 Nov 09 '20 at 09:38
  • OMG, many things that I did not know. it was very helpful, really appreciated! all my problems have been solved. I wonder if you know how can I add a linebreak between version and encoding? I have tried \n but it does it work. – ShrnPrmshr Nov 09 '20 at 10:05
  • @ShrnPrmshr [You can't](https://source.dot.net/#System.Private.Xml.Linq/System/Xml/Linq/XDeclaration.cs,104). You might be able to subclass `XDeclaration` and override `ToString` however... Worth trying. – canton7 Nov 09 '20 at 10:06
  • I could guess that, but how about other lines than this root? I want to be able to add linebreaks both between each attribute and even sometimes split and break for the next line in some texts. It seems \n does not work at all – ShrnPrmshr Nov 09 '20 at 10:15
  • @ShrnPrmshr If you want that level of control, you probably want to be using something lower-level than `XDocument`, such as `XmlWriter` – canton7 Nov 09 '20 at 10:28
  • I see, actually, I only need that for one XElement after that root. I have a lot of XElements which will be added that to that XElement I need linebreak for it. so maybe the question if we can add list to an XmlWriter then – ShrnPrmshr Nov 09 '20 at 10:32
  • Well, that's what `XDocument` does, but it doesn't give you control over how exactly they should be formatted. As with most things in programming, you either get low-level control (which takes a lot of effort), or a high-level abstraction which takes a way a lot of the effort but also removes control, but not both. Maybe you can use `XDocument` to write your XML, then read it back using an `XmlReader` and re-format it then? – canton7 Nov 09 '20 at 10:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/224320/discussion-between-shrnprmshr-and-canton7). – ShrnPrmshr Nov 09 '20 at 12:04
0
<?xml version="1.0" encoding="utf-8"?>. 

to do so you need an XDeclaration with XDocument

XDocument doc = new XDocument(  
    new XDeclaration("1.0", "utf-8", "yes")
);  
Ismail Diari
  • 498
  • 3
  • 8