10

Right now I am using:

XElement xe = XElement.ReadFrom

which requires an XmlReader:

XmlReader reader = XmlTextReader.Create

which requires a string, and that requires me to pass a StringReader:

new StringReader

which requires a TextReader/StreamReader to finally be able to pass the file path to it:

TextReader textReader = new StreamReader ( file );

Is the simpliest way to do this? I already have code that uses an XElement so it works fine but I want to cut down the number of steps to get the XElement from an xml file. Something like:

XElement xe = XElement.ReadFrom (string file);

Any ideas?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689

2 Answers2

11

Joan, use XDocument.Load(string):

XDocument doc = XDocument.Load("PurchaseOrder.xml");

Some comments:

  1. You should never use XmlTextReader.Create. use XmlReader.Create. It's a static method, so it doesn't make a difference which derived class you use to refer to it. It's misleading to use XmlTextReader.Create, since it looks like that's different from XmlReader.Create. It's not.
  2. XmlReader.Create has an overload that accepts a string, just like XDocument.Load does: XmlReader.Create(string inputUri).
  3. There's actually no such thing as XElement.ReadFrom. It's actually XNode.ReadFrom.
John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • Thanks John, but if I do that, can I still do xe.Elements("something").Elements("else").Select, etc? – Joan Venge Feb 26 '11 at 00:48
  • 1
    Joan, yes. There's no such thing as `XElement.Elements`. It's [`XContainer.Elements`](http://msdn.microsoft.com/en-us/library/bb348975.aspx). I strongly suggest you start noticing which class things are defined in. Many are inherited. – John Saunders Feb 26 '11 at 00:53
  • Thanks John, so do static methods get carried to all derived types? Also you said XmlReader.Create takes a string, but that's not a file path (to read the file contents), right? Lastly I now saw that XElement.ReadFrom is XNode.ReadFrom, but in that case, how does it appear under XElement? Same inheritance deal? – Joan Venge Feb 26 '11 at 00:57
  • 1
    @Joan: yes, statics are always inherited (assuming they're not `private`). The `XmlReader.Create` overload that takes a string treats it as a URI, but "filename.typ" is treated just like a file path. Yes, same inheritance deal. – John Saunders Feb 26 '11 at 01:02
  • Thanks, then in that case, should I use XDocument.Load or XmlReader.Create for the file path as a best practice? – Joan Venge Feb 26 '11 at 02:33
  • 1
    @Joan: it doesn't matter. `XDocument.Load(string)` almost certainly calls `using (XmlReader reader = XmlReader.Create(string)) {return XDocument.Load(reader);}`. In other words, _everything_ eventually comes down to an `XmlReader`. – John Saunders Feb 26 '11 at 02:36
  • Thanks John, appreciate your help. My code now works good and is more elegant too. – Joan Venge Feb 26 '11 at 03:24
4
XElement.ReadFrom(XmlReader.Create(fileName))

But explicitly managing file stream objects and XmlReader objects is better - you know when streams are closed...

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • So if you do this, the reader and stream objects will leak memory? – Joan Venge Feb 26 '11 at 00:50
  • 2
    @Joan: no, they don't leak resources (they never leak memory under any circumstances) - it's just that the resources won't get cleaned up until the garbage collector eventually gets around to it. – John Saunders Feb 26 '11 at 00:54
  • If you're concerned about releasing resources, as a good programmer should be, you can wrap your code in a using statement since XmlReader implements IDisposable: `using (var reader = XmlReader.Create("SomeFile.xml")) { var element = XElement.ReadFrom(reader); }` – SteveB Nov 14 '19 at 16:57