XML Input

Creating and persisting XML to a file does no good if you can't load it back into an XML tree. Here are some techniques to read XML back in.

Loading with XDocument.Load()

Now that you know how to save your XML documents and fragments, you would probably like to know how to load them. You can load your XML document using any of several methods. Here is a list:

static XDocument XDocument.Load(string uri);
static XDocument XDocument.Load(TextReader textReader);
static XDocument XDocument.Load(XmlReader reader);
static XDocument XDocument.Load(string uri, LoadOptions options);
static XDocument XDocument.Load(TextReader textReader, LoadOptions options);
static XDocument XDocument.Load(XmlReader reader, LoadOptions options);

You may notice how symmetrical these methods are to the XDocument.Save methods. However, there are a couple differences worth pointing out. First, in the Save methods, you must call the Save method on an object of XDocument or XElement type because the Save method is an instance method. But the Load method is static, so you must call it on the XDocument class itself. Second, the Save methods that accept a string are requiring filenames to be passed, whereas the Load methods that accept a string are allowing a URI to be passed.

Additionally, the Load method allows a parameter of type LoadOptions to be specified while loading the XML document. The LoadOptions enum has the options shown in Table 7-2.

Table The LoadOptions Enumeration
OptionDescription
LoadOptions.NoneUse this option to specify that no load options are to be used.
LoadOptions.PreserveWhitespaceUse this option to preserve the whitespace in the XML source, such as blank lines.
LoadOptions.SetLineInfoUse this option so that you may obtain the line and position of any object inheriting from XObject by using the IXmlLineInfo interface.
LoadOptions.SetBaseUriUse this option so that you may obtain the base URI of any object inheriting from XObject.

These options can be combined with a bitwise OR (|) operation. However, some options will not work in some contexts. For example, when creating an element or a document by parsing a string, there is no line information available, nor is there a base URI. Or, when creating a document with an XmlReader, there is no base URI.

Listing 7-38 shows an example where I load my XML document created in the previous example, Listing 7-37.

Example. Loading a Document with the XDocument.Load Method
XDocument xDocument = XDocument.Load("bookparticipants.xml",
  LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);

Console.WriteLine(xDocument);

XElement firstName = xDocument.Descendants("FirstName").First();

Console.WriteLine("FirstName Line:{0} - Position:{1}",
  ((IXmlLineInfo)firstName).LineNumber,
  ((IXmlLineInfo)firstName).LinePosition);

Console.WriteLine("FirstName Base URI:{0}", firstName.BaseUri);

NOTE

You must either add a using directive for System.Xml, if one is not present, or specify the namespace when referencing the IXmlLineInfo interface in your code; otherwise, the IXmlLineInfo type will not be found.

This code is loading the same XML file I created in the previous example. After I load and display the document, I obtain a reference for the FirstName element and display the line and position of the element in the source XML document. Then I display the base URI for the element.

Here are the results:

<BookParticipants>
  <BookParticipant type="Author" experience="first-time" language="English">
    <FirstName>Joe</FirstName>
    <LastName>Rattz</LastName>
  </BookParticipant>
</BookParticipants>
FirstName Line:4 - Position:6
FirstName Base URI:file:///C:/Documents and Settings/.../Projects/LINQChapter7/
LINQChapter7/bin/Debug/bookparticipants.xml

This output looks just as I would expect, with one possible exception. First, the actual XML document looks fine. I see the line and position of the FirstName element, but the line number is causing me concern. It is shown as four, but in the displayed XML document, the FirstName element is on the third line. What is that about? If you examine the XML document I loaded, you will see that it begins with the document declaration, which is omitted from the output:

<?xml version="1.0" encoding="utf-8"?>

This is why the FirstName element is being reported as being on line four.

Loading with XElement.Load()

Just as you could save from either an XDocument or XElement, we can load from either as well. Loading into an element is virtually identical to loading into a document. Here are the methods available:

static XElement XElement.Load(string uri);
static XElement XElement.LoadTextReader textReader);
static XElement XElement.Load(XmlReader reader);
static XElement XElement.Load(string uri, LoadOptions options);
static XElement XElement.Load(TextReader textReader, LoadOptions options);
static XElement XElement.Load(XmlReader reader, LoadOptions options);

These methods are static just like the XDocument.Save methods, so they must be called from the XElement class directly. Listing 7-39 contains an example loading the same XML file I saved with the XElement.Save method in Listing 7-37.

Example. Loading an Element with the XElement.Load Method
XElement xElement = XElement.Load("bookparticipants.xml");
Console.WriteLine(xElement);

Just as you already expect, the output looks like the following:

<BookParticipants>
  <BookParticipant type="Author" experience="first-time" language="English">
    <FirstName>Joe</FirstName>
    <LastName>Rattz</LastName>
  </BookParticipant>
</BookParticipants>

Just as the XDocument.Load method does, the XElement.Load method has overloads that accept a LoadOptions parameter. Please see the description of these in the "Loading with XDocument.Load()" section previously in the chapter.

Parsing with XDocument.Parse() or XElement.Parse()

How many times have you passed XML around in your programs as a string, only to suddenly need to do some serious XML work? Getting the data from a string variable to an XML document type variable always seems like such a hassle. Well, worry yourself no longer. One of my personal favorite features of the LINQ to XML API is the parse method.

Both the XDocument and XElement classes have a static method named Parse for parsing XML strings. I think by now you probably feel comfortable accepting that if you can parse with the XDocument class, you can probably parse with the XElement class, and vice-versa. And since the LINQ to XML API is all about the elements, baby, I am going to only give you an element example this time:

In the "Saving with XDocument.Save" section earlier in this chapter, I show the output of the Save method if the LoadOptions parameter is specified as DisableFormatting. The result is a single string of XML. For the example in Listing 7-40, I start with that XML string (after escaping the inner quotes), parse it into an element, and output the XML element to the screen.

Example. Parsing an XML String into an Element
string xml = "<?xml version="1.0" encoding="utf-8"?><BookParticipants>" +
  "<BookParticipant type="Author" experience="first-time" language=" +
  ""English"><FirstName>Joe</FirstName><LastName>Rattz</LastName>" +
  "</BookParticipant></BookParticipants>";

XElement xElement = XElement.Parse(xml);
Console.WriteLine(xElement);

The results are the following:

<BookParticipants>
  <BookParticipant type="Author" experience="first-time" language="English">
    <FirstName>Joe</FirstName>
    <LastName>Rattz</LastName>
  </BookParticipant>
</BookParticipants>

How cool is that? Remember the old days when you had to create a document using the W3C XML DOM XmlDocument class? Thanks to the elimination of document centricity, you can turn XML strings into real XML trees in the blink of an eye with one method call.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset