Indent with tabs instead of spaces in XML - c#

Okay so I have some code which is supposed to change a value in a configuration file.
string xmlFile = "KeePass.config.xml";
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
XmlWriterSettings settings = new XmlWriterSettings();
settings.IndentChars = "\t";
settings.Indent = true;
xmlDoc.Load(xmlFile);
xmlDoc.SelectSingleNode("Configuration/Application/LastUsedFile").InnerText = fileName;
xmlDoc.Save(xmlFile);
The problem with this is that it indents the XML file with spaces instead of tabs and the program which reads the configuration file needs to see the XML with tab indents. Any help would be appreciated.

Have you tried
xmlDoc.PreserveWhitespace = true;

Related

Serializing class structure to XML seems to add a NewLine character

The code below serializes XML into a string, then writes it to an XML file (yes quite a bit going on with respect to UTF8 and removal of the Namespace):
var bidsXml = string.Empty;
var emptyNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
activity = $"Serialize Class INFO to XML to string";
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
{
XmlSerializer xml = new XmlSerializer(info.GetType());
xml.Serialize(writer, info, emptyNamespaces);
bidsXml = Encoding.UTF8.GetString(stream.ToArray());
}
var lastChar = bidsXml.Substring(bidsXml.Length);
var fileName = $"CostOffer_Testing_{DateTime.Now:yyyy.MM.dd_HH.mm.ss}.xml";
var path = $"c:\\temp\\pjm\\{fileName}";
File.WriteAllText(path, bidsXml);
Problem is, serialization to XML seems to introduce a CR/LF (NewLine):
It's easier to see in the XML file:
A workaround is to strip out the "last" character:
bidsXml = bidsXml.Substring(0,bidsXml.Length - 1);
But better is to understand the root cause and resolve without a workaround - any idea why this a NewLine characters is being appended to the XML string?
** EDIT **
I was able to attempt a load into the consumer application (prior to this attempt I used an API to import the XML), and I received a more telling message:
The file you are loading is a binary file, the contents can not be displayed here.
So i suspect an unprintable characters is somehow getting embedded into the file/XML. When I open the file in Notepad++, I see the following (UFF-8-Byte Order Mark) - at least I have something to go on:
So it seems the consumer of my XML does not want BOM (Byte Order Mark) within the stream.
Visiting this site UTF-8 BOM adventures in C#
I've updated my code to use new UTF8Encoding(false)) rather than Encoding.UTF8:
var utf8NoBOM = new UTF8Encoding(false);
var bidsXml = string.Empty;
var emptyNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
activity = $"Serialize Class INFO to XML to string";
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream, utf8NoBOM))
{
XmlSerializer xml = new XmlSerializer(info.GetType());
xml.Serialize(writer, info, emptyNamespaces);
bidsXml = utf8NoBOM.GetString(stream.ToArray());
}
var fileName = $"CostOffer_Testing_{DateTime.Now:yyyy.MM.dd_HH.mm.ss}.xml";
var path = $"c:\\temp\\pjm\\{fileName}";
File.WriteAllText(path, bidsXml, utf8NoBOM);

Converting XML to UTF-8 using C#

I have written below code to convert XML file to UTF-8 format file, it is working as excepted but issue is header is concatenating with body text instead of writing in separate line. I need utf8 in seperate line but file.writealltext will not accept more than 3 arguments/parameters. Any help appreciated.
string path = #"samplefile.xml";
string path_new = #"samplefile_new.xml";
Encoding utf8 = new UTF8Encoding(false);
Encoding ansi = Encoding.GetEncoding(1252);
string xml = File.ReadAllText(path, ansi);
XDocument xmlDoc = XDocument.Parse(xml);
File.WriteAllText(
path_new,
#"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""true"">" + xmlDoc.ToString(),
utf8
);
No need to use any API other than LINQ to XML. It has all means to deal with XML file encoding, prolog, BOM, indentation, etc.
void Main()
{
string outputXMLfile = #"e:\temp\XMLfile_UTF-8.xml";
XDocument xml = XDocument.Parse(#"<?xml version='1.0' encoding='utf-16'?>
<root>
<row>some text</row>
</root>");
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", null),
new XElement(xml.Root)
);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = "\t";
// to remove BOM
settings.Encoding = new UTF8Encoding(false);
using (XmlWriter writer = XmlWriter.Create(outputXMLfile, settings))
{
doc.Save(writer);
}
}

Save XML file without formatting

I have a XML file that needs to be saved without formatting, without identation and line breaks. I'm doing it this way:
using (var writer = System.IO.File.CreateText("E:\\nfse.xml"))
{
var doc = new XmlDocument { PreserveWhitespace = false };
doc.Load("E:\\notafinal.xml");
writer.WriteLine(doc.InnerXml);
writer.Flush();
}
But that way I need to create the file, and then I need to change it 3 times, so in the end there are a total of 4 files, the initial one and the result of the 3 changes.
When I save the file, I do it this way:
MemoryStream stream = stringToStream(soapEnvelope);
webRequest.ContentLength = stream.Length;
Stream requestStream = webRequest.GetRequestStream();
stream.WriteTo(requestStream);
document.LoadXml(soapEnvelope);
document.PreserveWhitespace = false;
document.Save(#"E:\\notafinal.xml");
How can I do this without having to create a new document?
If what you want is to eliminate extra space by not formatting the XML file, you could use XmlWriterSettings and XmlWriter, like this:
public void SaveXmlDocToFile(XmlDocument xmlDoc,
string outputFileName,
bool formatXmlFile = false)
{
var settings = new XmlWriterSettings();
if (formatXmlFile)
{
settings.Indent = true;
}
else
{
settings.Indent = false;
settings.NewLineChars = String.Empty;
}
using (var writer = XmlWriter.Create(outputFileName, settings))
xmlDoc.Save(writer);
}
Passing formatXmlFile = false in the parameters will save the XML file without formatting it.

How to get XML with header (<?xml version="1.0"...)?

Consider the following simple code which creates an XML document and displays it.
XmlDocument xml = new XmlDocument();
XmlElement root = xml.CreateElement("root");
xml.AppendChild(root);
XmlComment comment = xml.CreateComment("Comment");
root.AppendChild(comment);
textBox1.Text = xml.OuterXml;
it displays, as expected:
<root><!--Comment--></root>
It doesn't, however, display the
<?xml version="1.0" encoding="UTF-8"?>
So how can I get that as well?
Create an XML-declaration using XmlDocument.CreateXmlDeclaration Method:
XmlNode docNode = xml.CreateXmlDeclaration("1.0", "UTF-8", null);
xml.AppendChild(docNode);
Note: please take a look at the documentation for the method, especially for encoding parameter: there are special requirements for values of this parameter.
You need to use an XmlWriter (which writes the XML declaration by default). You should note that that C# strings are UTF-16 and your XML declaration says that the document is UTF-8 encoded. That discrepancy can cause problems. Here's an example, writing to a file that gives the result you expect:
XmlDocument xml = new XmlDocument();
XmlElement root = xml.CreateElement("root");
xml.AppendChild(root);
XmlComment comment = xml.CreateComment("Comment");
root.AppendChild(comment);
XmlWriterSettings settings = new XmlWriterSettings
{
Encoding = Encoding.UTF8,
ConformanceLevel = ConformanceLevel.Document,
OmitXmlDeclaration = false,
CloseOutput = true,
Indent = true,
IndentChars = " ",
NewLineHandling = NewLineHandling.Replace
};
using ( StreamWriter sw = File.CreateText("output.xml") )
using ( XmlWriter writer = XmlWriter.Create(sw,settings))
{
xml.WriteContentTo(writer);
writer.Close() ;
}
string document = File.ReadAllText( "output.xml") ;
XmlDeclaration xmldecl;
xmldecl = xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = xmlDocument.DocumentElement;
xmlDocument.InsertBefore(xmldecl, root);

Writing XMLDocument to file with specific newline character (c#)

I have an XMLDocument that I have read in from file. The file is Unicode, and has the newline character '\n'. When I write the XMLDocument back out, it has the newline characters '\r\n'.
Here is the code, pretty simple:
XmlTextWriter writer = new XmlTextWriter(indexFile + ".tmp", System.Text.UnicodeEncoding.Unicode);
writer.Formatting = Formatting.Indented;
doc.WriteTo(writer);
writer.Close();
XmlWriterSettings has a property, NewLineChars, but I am unable to specify the settings parameter on 'writer', it is read-only.
I can create a XmlWriter with a specified XmlWriterSettings property, but XmlWriter does not have a formatting property, resulting in a file with no linebreaks at all.
So, in short, I need to write a Unicode Xml file with newline character '\n' and Formatting.Indented. Thoughts?
I think you're close. You need to create the writer from the settings object:
(Lifted from the XmlWriterSettings MSDN page)
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
settings.NewLineOnAttributes = true;
writer = XmlWriter.Create(Console.Out, settings);
writer.WriteStartElement("order");
writer.WriteAttributeString("orderID", "367A54");
writer.WriteAttributeString("date", "2001-05-03");
writer.WriteElementString("price", "19.95");
writer.WriteEndElement();
writer.Flush();
Use XmlWriter.Create() to create the writer and specify the format. This worked well:
using System;
using System.Xml;
class Program {
static void Main(string[] args) {
XmlWriterSettings settings = new XmlWriterSettings();
settings.NewLineChars = "\n";
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(#"c:\temp\test.xml", settings);
XmlDocument doc = new XmlDocument();
doc.InnerXml = "<root><element>value</element></root>";
doc.WriteTo(writer);
writer.Close();
}
}

Categories