I am wondering how to add a line break for each element when using XmlSerializer?
Sample code:
XmlSerializer serializer = new XmlSerializer(typeof(xxx));
using (XmlWriter xmlWriter = XmlWriter.Create("test.xml")
{
serializer.Serialize(xmlWriter, xxx);
}
When creating the XmlWriter, pass in an XmlWriterSettings object with Indent set to true.
var xmlWriterSettings = new XmlWriterSettings() { Indent = true };
XmlSerializer serializer = new XmlSerializer(typeof(xxx));
using (XmlWriter xmlWriter = XmlWriter.Create("test.xml", xmlWriterSettings)
{
serializer.Serialize(xmlWriter, xxx);
}
You can use XmlWriterSettings and set the properties to out the indentation and newlines. .Indent and .NewLineOnAttributes seem to be what you would want.
http://msdn.microsoft.com/en-us/library/system.xml.xmlwritersettings.aspx
Related
Im trying the serialize the modelstate to an xml string. First I create a modelstate dictionary and this dictionary I try to serialize. This is the code I use:
ModelStateDictionary dict = new ModelStateDictionary();
dict.Merge(ModelState);
XmlSerializer serializer = new XmlSerializer(dict.GetType());
using (StringWriter writer = new StringWriter()){
serializer.Serialize(writer, dict);
var r2 = writer.ToString();
}
r2 is created, but all tags are filled with \r\n. What am I doing wrong?
You could use a XmlWriter and specify in the settings that you don't want to keep whitespaces and indentation:
XmlSerializer serializer = new XmlSerializer(dict.GetType());
var settings = new XmlWriterSettings { Indent = false };
using (var stream = new MemoryStream())
using (var writer = XmlWriter.Create(stream, settings))
{
serializer.Serialize(writer, dict);
string r2 = Encoding.UTF8.GetString(stream.ToArray());
}
I am using an XmlSerializer to serialize an object to xml. After the object gets serialized, I end up with something like...
<?xml version="1.0" encoding="utf-8"?>
<xml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</xml>
I need to have it return simply...
<xml></xml>
Is there a way to serialize xml without the extra information? I realize strictly proper xml requires these additional elements, but I need the simpler form as I am appending these xml strings together to form a larger xml blob.
UPDATE
I was able to get the following code to work...
public static string Serialize(object o)
{
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = true;
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add(String.Empty, String.Empty);
StringBuilder sb = new StringBuilder();
XmlWriter xmlw = XmlWriter.Create(sb, xws);
XmlSerializer serializer = new XmlSerializer(o.GetType());
serializer.Serialize(xmlw, o, ns);
xmlw.Flush();
return sb.ToString();
}
In C#, you can do something like this:
XmlSerializer serializer = new XmlSerializer(typeof(object));
StringWriter stringWriter = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(stringWriter, new XmlWriterSettings() { OmitXmlDeclaration = true }))
{
serializer.Serialize(writer, this, new XmlSerializerNamespaces() { "",""});
}
string xmlText = stringWriter.ToString();
Explanation:
OmitXmlDeclaration = true makes it remove the declaration.
new XmlSerializerNamespaces() { "",""} removes the namespaces.
I am using the following code to create an xml document -
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
new XmlSerializer(typeof(docket)).Serialize(Console.Out, i, ns);
this works great in creating the xml file with no namespace attributes. i would like to also have no encoding attribute in the root element, but I cannot find a way to do it. Does anyone have any idea if this can be done?
Thanks
Old answer removed and update with new solution:
Assuming that it's ok to remove the xml declaration completly, because it makes not much sense without the encoding attribute:
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", "");
using (XmlWriter writer = XmlWriter.Create(Console.Out, new XmlWriterSettings { OmitXmlDeclaration = true}))
{
new XmlSerializer(typeof (SomeType)).Serialize(writer, new SomeType(), ns);
}
To remove encoding from XML header pass TextWriter with null encoding to XmlSerializer:
MemoryStream ms = new MemoryStream();
XmlTextWriter w = new XmlTextWriter(ms, null);
s.Serialize(w, vs);
Explanation
XmlTextWriter uses encoding from TextWriter passed in constructor:
// XmlTextWriter constructor
public XmlTextWriter(TextWriter w) : this()
{
this.textWriter = w;
this.encoding = w.Encoding;
..
It uses this encoding when generating XML:
// Snippet from XmlTextWriter.StartDocument
if (this.encoding != null)
{
builder.Append(" encoding=");
...
string withEncoding;
using (System.IO.MemoryStream memory = new System.IO.MemoryStream()) {
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(memory)) {
serializer.Serialize(writer, obj, null);
using (System.IO.StreamReader reader = new System.IO.StreamReader(memory)) {
memory.Position = 0;
withEncoding= reader.ReadToEnd();
}
}
}
string withOutEncoding= withEncoding.Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "");
Credit to this blog for helping me with my code
http://blog.dotnetclr.com/archive/2008/01/29/removing-declaration-and-namespaces-from-xml-serialization.aspx
here's my solution, same idea, but in VB.NET and a little clearer in my opinion.
Dim sw As StreamWriter = New, StreamWriter(req.GetRequestStream,System.Text.Encoding.ASCII)
Dim xSerializer As XmlSerializer = New XmlSerializer(GetType(T))
Dim nmsp As XmlSerializerNamespaces = New XmlSerializerNamespaces()
nmsp.Add("", "")
Dim xWriterSettings As XmlWriterSettings = New XmlWriterSettings()
xWriterSettings.OmitXmlDeclaration = True
Dim xmlWriter As XmlWriter = xmlWriter.Create(sw, xWriterSettings)
xSerializer.Serialize(xmlWriter, someObjectT, nmsp)
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();
}
}
I am creating an ASHX that returns XML however it expects a path when I do
XmlWriter writer = XmlWriter.Create(returnXML, settings)
But returnXML is just an empty string right now (guess that won't work), however I need to write the XML to something that I can then send as the response text. I tried XmlDocument but it gave me an error expecting a string. What am I missing here?
If you really want to write into memory, pass in a StringWriter or a StringBuilder like this:
using System;
using System.Text;
using System.Xml;
public class Test
{
static void Main()
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
StringBuilder builder = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(builder, settings))
{
writer.WriteStartDocument();
writer.WriteStartElement("root");
writer.WriteStartElement("element");
writer.WriteString("content");
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
}
Console.WriteLine(builder);
}
}
If you want to write it directly to the response, however, you could pass in HttpResponse.Output which is a TextWriter instead:
using (XmlWriter writer = XmlWriter.Create(Response.Output, settings))
{
// Write into it here
}
Something was missing on my side: flushing the XmlWriter's buffer:
static void Main()
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
StringBuilder builder = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(builder, settings))
{
writer.WriteStartDocument();
writer.WriteStartElement("root");
writer.WriteStartElement("element");
writer.WriteString("content");
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
}
Console.WriteLine(builder);
}
StringBuilder xml = new StringBuilder();
TextWriter textWriter = new StringWriter(xml);
XmlWriter xmlWriter = new XmlTextWriter(textWriter);
Then, use the xmlWriter to do all the xml writing, and that writes it directly to the StringBuilder.
Edit: Thanks to Jon Skeet's comment:
StringBuilder xml = new StringBuilder();
XmlWriter xmlWriter = XmlWriter.Create(xml);
The best way to do that is to write directly to the Response Output Stream. Its a stream that's built-in to ASP.NET to allow you to write whatever output as a stream, in this case you can write XML to it.