How do I serialize an object into an XDocument? - c#

I have a class that is marked with DataContract attributes and I would like to create an XDocument from objects of that class. Whats the best way of doing this?
I can do it by going via an XmlDocument but this seems like an unnecessary step.

You can create an XmlWriter directly into the XDocument:
XDocument doc = new XDocument();
using (var writer = doc.CreateWriter())
{
// write xml into the writer
var serializer = new DataContractSerializer(objectToSerialize.GetType());
serializer.WriteObject(writer, objectToSerialize);
}
Console.WriteLine(doc.ToString());

this is how i do it, which gives clean xml without all the namespace stuff in it,
XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
using (var writer = xdoc.CreateWriter())
{
System.Xml.Serialization.XmlSerializer x =
new System.Xml.Serialization.XmlSerializer(objecttoserialize.GetType());
x.Serialize(writer, objecttoserialize);
}
Debug.WriteLine(xdoc.ToString());

Related

How to use XmlDocument object instead of reading XML file from drive?

I didn't know that I can use XSD schema to serialize received XML file. I used xsd.exe to generate cs class from XSD file and now I need to use that class to get data in class properties but I miss one thing and I need help.
This is the code:
private void ParseDataFromXmlDocument_UsingSerializerClass(XmlDocument doc)
{
XmlSerializer ser = new XmlSerializer(typeof(ClassFromXsd));
string filename = Path.Combine("C:\\myxmls\\test", "xmlname.xml");
ClassFromXsdmyClass = ser.Deserialize(new FileStream(filename, FileMode.Open)) as ClassFromXsd;
if (myClass != null)
{
// to do
}
...
Here I use XML file from drive. And I want to use this XmlDocument from parameter that I passed in. So how to adapt this code to use doc instead XML from drive?
You could write the XmlDocument to a MemoryStream, and then Deserialize it like you already did.
XmlDocument doc = new XmlDocument();
ClassFromXsd obj = null;
using (var s = new MemoryStream())
{
doc.Save(s);
var ser = new XmlSerializer(typeof (ClassFromXsd));
s.Seek(0, SeekOrigin.Begin);
obj = (ClassFromXsd)ser.Deserialize(s);
}

Obtaining XmlElement from XDocument

I have to pass a whole XML document into a 3rd party function. The parameter is XmlElement.
To do this until now, I've successfully been using this:
XmlDocument doc;
//doc = ...
XmlElement root = doc.DocumentElement;
3rdPartyFunction(root);
But now I'm using XDocument instead of XmlDocument:
XDocument doc;
//doc = ...
//how to call 3rdPartyFunction?
How do I call the function in this case? Can I convert from "Xml" to "X"?
Use this:
var newDoc = new XmlDocument();
newDoc.LoadXml(doc.ToString());
3rdPartyFunction(newDoc);
[Updated]
XmlDocument xmldoc = new XmlDocument();
using (XmlReader reader = xdoc.CreateReader())
{
xmldoc.Load(reader);
}
XmlElement root = xmldoc.DocumentElement;
3rdPartyFunction(root);

Overwriting root element in syndicationfeed, Adding namespaces to root element

I need to add new namespaces to the rss(root) element of my feed, in addition to a10:
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
<channel>
.
.
.
I am using a SyndicationFeed class serialized to RSS 2.0 and I use a XmlWriter to output the feed,
var feed = new SyndicationFeed(
feedDefinition.Title,
feedDefinition.Description,
.
.
.
using (var writer = XmlWriter.Create(context.HttpContext.Response.Output, settings))
{
rssFormatter.WriteTo(writer);
}
I have tried adding AttributeExtensions on SyndicationFeed but it adds the new namespaces
to the channel element instead of the root,
Thank you
Unfortunately the formatter is not extensible in the way you need.
You can use an intermediate XmlDocument and modify it before writing to the final output.
This code will add a namespace to the root element of the final xml output:
var feed = new SyndicationFeed("foo", "bar", new Uri("http://www.example.com"));
var rssFeedFormatter = new Rss20FeedFormatter(feed);
// Create a new XmlDocument in order to modify the root element
var xmlDoc = new XmlDocument();
// Write the RSS formatted feed directly into the xml doc
using(var xw = xmlDoc.CreateNavigator().AppendChild() )
{
rssFeedFormatter.WriteTo(xw);
}
// modify the document as you want
xmlDoc.DocumentElement.SetAttribute("xmlns:example", "www.example.com");
// now create your writer and output to it:
var sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb))
{
xmlDoc.WriteTo(writer);
}
Console.WriteLine(sb.ToString());

.net: XmlDocument creates one line xml document

I have a standard XML document, which looks like a 'tree'. I add some nodes and save changes:
XmlDocument doc = new XmlDocument();
doc.Load(filename);
...
doc.PreserveWhitespace = true;
XmlTextWriter writer = new XmlTextWriter(filename, Encoding.Default);
doc.WriteTo(writer);
writer.Close();
and after that xml document stretch into one line. How to add line feeds?
After you construct the XmlTextWriter, but before you call doc.WriteTo(writer);, insert this line:
writer.Formatting = Formatting.Indented;

XDocument.Save() without header

I am editing csproj files with Linq-to-XML and need to save the XML without the <?XML?> header.
As XDocument.Save() is missing the necessary option, what's the best way to do this?
You can do this with XmlWriterSettings, and saving the document to an XmlWriter:
XDocument doc = new XDocument(new XElement("foo",
new XAttribute("hello","world")));
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
StringWriter sw = new StringWriter();
using (XmlWriter xw = XmlWriter.Create(sw, settings))
// or to write to a file...
//using (XmlWriter xw = XmlWriter.Create(filePath, settings))
{
doc.Save(xw);
}
string s = sw.ToString();
A simpler solution than the accepted answer is to use XDocument.ToString() to get the XML text without the header.
Example:
// Load the file
XDocument xDocument = XDocument.Load(fileName);
// Edit the XML...
// Save the edited XML text to file
File.WriteAllText(fileName, xDocument.ToString());

Categories

Resources