tags:

views:

129

answers:

2

I have the following variable that accepts a file name:

var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);

I would like to change it so that I can pass in an object. I don't want to have to serialize the object to file first.

Is this possible?

Update:

My original intentions were to take an xml document, merge some xslt (stored in a file), then output and return html... like this:

public string TransformXml(string xmlFileName, string xslFileName)
{
     var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
     var xd = new XmlDocument();
     xd.Load(xtr);

     var xslt = new System.Xml.Xsl.XslCompiledTransform();
     xslt.Load(xslFileName);
     var stm = new MemoryStream();
     xslt.Transform(xd, null, stm);
     stm.Position = 1;
     var sr = new StreamReader(stm);
     xtr.Close();
     return sr.ReadToEnd();
}

In the above code I am reading in the xml from a file. Now what I would like to do is just work with the object, before it was serialized to the file.

So let me illustrate my problem using code

public string TransformXMLFromObject(myObjType myobj , string xsltFileName)
{
     // Notice the xslt stays the same.
     // Its in these next few lines that I can't figure out how to load the xml document (xd) from an object, and not from a file....

     var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
     var xd = new XmlDocument();
     xd.Load(xtr);
}
+6  A: 

You want to turn an arbitrary .NET object into a serialized XML string? Nothing simpler than that!! :-)

public string SerializeToXml(object input)
{
   XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
   string result = string.Empty;

   using(MemoryStream memStm = new MemoryStream())
   {
     ser.Serialize(memStm, input);

     memStm.Position = 0;
     result = new StreamReader(memStm).ReadToEnd();
   } 

   return result;
} 

That should to it :-) Of course you might want to make the default XML namespace configurable as a parameter, too.

Or do you want to be able to create an XmlDocument on top of an existing object?

public XmlDocument SerializeToXmlDocument(object input)
{
   XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");

   XmlDocument xd = null;

   using(MemoryStream memStm = new MemoryStream())
   {
     ser.Serialize(memStm, input);

     memStm.Position = 0;

     XmlReaderSettings settings = new XmlReaderSettings();
     settings.IgnoreWhitespace = true;

     using(var xtr = XmlReader.Create(memStm, settings))
     {  
        xd = new XmlDocument();
        xd.Load(xtr);
     }
   }

   return xd;
}
marc_s
@marc_s: ick! No `using` blocks! `new XmlTextReader()`! -1!
John Saunders
@John: I was just fixing the `new XmlTextReader()`.... you're too quick to downvote......
marc_s
@John: but explain to me in simple and easy to understand words the benefit of `XmlReader.Create()` vs. `new XmlTextReader()` - nobody has made a compelling point so far.....
marc_s
@marc_s: why not use StringWriter and StringReader, rather than MemoryStream and StreamReader ? I think it would make more sense here ;). Regarding XmlReader.Create, it's just a MS recommendation... I don't know the exact reason
Thomas Levesque
Ok testing now...
JL
@Thomas: why?? What do you think would be the benefit of StringWriter vs. MemoryStream? Just curious.... you might be totally right, I've never considered using a StringWriter here.....
marc_s
@marc_s, re: `XmlReader.Create()` vs `new XmlTextReader()`, it's a basic factory vs constructor. Maybe it's a good topic for your own question, heh heh. @Every one else: the critics are out!
Cheeso
@marc_s, quote from the doc: `Although the Microsoft .NET Framework includes concrete implementations of the XmlReader class, such as the XmlTextReader, XmlNodeReader, and the XmlValidatingReader classes, in the .NET Framework version 2.0, we recommend that you create XmlReader instances using the Create method` (http://msdn.microsoft.com/en-us/library/9khb6435.aspx). I guess the only compelling reason might be that if in .NET 7.9 they introduce the `HyperXmlReader` class you won't need to change your code to benefit from it :-)
Darin Dimitrov
@marc_s: in your second piece of code, it doesn't change anything. But in the first one, you're returning a string, so using a MemoryStream and then reading it with a StreamReader to obtain a string seems a bit overcomplicated... with a StringWriter, you get a string directly
Thomas Levesque
Thanks Marc, it worked like a charm!
JL
@marc_s: It means you can be returned whatever `XmlReader` derivative may be appropriate, based on the `XmlReaderSettings`.
John Saunders
@John, @Thomas: thanks for your explanations and inputs! Highly appreciated - you learn something new (and useful) every day....
marc_s
+3  A: 

You can serialize directly into the XmlDocument:

XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
using (XmlWriter w = nav.AppendChild())
{
    XmlSerializer ser = new XmlSerializer(typeof(MyType));
    ser.Serialize(w, myObject);
}
John Saunders
I think the ser.Serializer doesn't accept the object as a parameter?
JL
uh, nice... and no intermediate string involved :)
Thomas Levesque
If I wasn't clear enough, the code above doesn't compile because ser.Serialize has some invalid parameters. Otherwise it looks like an elegant solution.
JL
@JL: I've been offline. Also, you'll want to use @user to get someone's attention. They'll be notified when you do. I've fixed the typo. The parameters were in the wrong order.
John Saunders
@John, thank you very much.
JL