Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Apress pro LINQ Language Integrated Query in C# 2008 phần 5 ppt
Nội dung xem thử
Mô tả chi tiết
218 CHAPTER 7 ■ THE LINQ TO XML API
Listing 7-34. Creating a Text Node and Passing It As the Value of a Created Element
XText xName = new XText("Joe");
XElement xFirstName = new XElement("FirstName", xName);
Console.WriteLine(xFirstName);
This code produces the exact same output as the previous example, and if we examine the internal
state of the xFirstName object, it too is identical to the one created in the previous example:
<FirstName>Joe</FirstName>
Creating CData with XCData
Creating an element with a CData value is also pretty simple. Listing 7-35 is an example.
Listing 7-35. Creating an XCData Node and Passing It As the Value of a Created Element
XElement xErrorMessage = new XElement("HTMLMessage",
new XCData("<H1>Invalid user id or password.</H1>"));
Console.WriteLine(xErrorMessage);
This code produces the following output:
<HTMLMessage><![CDATA[<H1>Invalid user id or password.</H1>]]></HTMLMessage>
As you can see, the LINQ to XML API makes handling CData simple.
XML Output
Of course, creating, modifying, and deleting XML data does no good if you cannot persist the changes.
This section contains a few ways to output your XML.
Saving with XDocument.Save()
You can save your XML document using any of several XDocument.Save methods. Here is a list of
prototypes:
void XDocument.Save(string filename);
void XDocument.Save(TextWriter textWriter);
void XDocument.Save(XmlWriter writer);
void XDocument.Save(string filename, SaveOptions options);
void XDocument.Save(TextWriter textWriter, SaveOptions options);
Listing 7-36 is an example where I save the XML document to a file in my project’s folder.
Rattz_789-3C07.fm Page 218 Tuesday, October 23, 2007 4:37 PM
CHAPTER 7 ■ THE LINQ TO XML API 219
Listing 7-36. Saving a Document with the XDocument.Save Method
XDocument xDocument = new XDocument(
new XElement("BookParticipants",
new XElement("BookParticipant",
new XAttribute("type", "Author"),
new XAttribute("experience", "first-time"),
new XAttribute("language", "English"),
new XElement("FirstName", "Joe"),
new XElement("LastName", "Rattz"))));
xDocument.Save("bookparticipants.xml");
Notice that I called the Save method on an object of type XDocument. This is because the Save
methods are instance methods. The Load methods you will read about later in the “XML Input”
section are static methods and must be called on the XDocument or XElement class.
Here are the contents of the generated bookparticipants.xml file when viewing them in a text
editor such as Notepad:
<?xml version="1.0" encoding="utf-8"?>
<BookParticipants>
<BookParticipant type="Author" experience="first-time" language="English">
<FirstName>Joe</FirstName>
<LastName>Rattz</LastName>
</BookParticipant>
</BookParticipants>
That XML document output is easy to read because the version of the Save method that I called
is formatting the output. That is, if I call the version of the Save method that accepts a string filename
and a SaveOptions argument, passing a value of SaveOptions.None would give the same results as the
previous. Had I called the Save method like this
xDocument.Save("bookparticipants.xml", SaveOptions.DisableFormatting);
the results in the file would look like this:
<?xml version="1.0" encoding="utf-8"?><BookParticipants><BookParticipant type=
"Author" experience="first-time" language="English"><FirstName>Joe</FirstName>
<LastName>Rattz</LastName></BookParticipant></BookParticipants>
This is one single continuous line of text. However, you would have to examine the file in a text
editor to see the difference because a browser will format it nicely for you.
Of course, you can use any of the other methods available to output your document as well; it’s
up to you.
Saving with XElement.Save()
I have said many times that with the LINQ to XML API, creating an XML document is not necessary.
And to save your XML to a file, it still isn’t. The XElement class has several Save methods for this purpose:
Rattz_789-3C07.fm Page 219 Tuesday, October 23, 2007 4:37 PM
220 CHAPTER 7 ■ THE LINQ TO XML API
void XElement.Save(string filename);
void XElement.Save(TextWriter textWriter);
void XElement.Save(XmlWriter writer);
void XElement.Save(string filename, SaveOptions options);
void XElement.Save(TextWriter textWriter, SaveOptions options);
Listing 7-37 is an example very similar to the previous, except I never even create an XML
document.
Listing 7-37. Saving an Element with the XElement.Save Method
XElement bookParticipants =
new XElement("BookParticipants",
new XElement("BookParticipant",
new XAttribute("type", "Author"),
new XAttribute("experience", "first-time"),
new XAttribute("language", "English"),
new XElement("FirstName", "Joe"),
new XElement("LastName", "Rattz")));
bookParticipants.Save("bookparticipants.xml");
And the saved XML looks identical to the previous example where I actually have an XML
document:
<?xml version="1.0" encoding="utf-8"?>
<BookParticipants>
<BookParticipant type="Author" experience="first-time" language="English">
<FirstName>Joe</FirstName>
<LastName>Rattz</LastName>
</BookParticipant>
</BookParticipants>
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);
Rattz_789-3C07.fm Page 220 Tuesday, October 23, 2007 4:37 PM
CHAPTER 7 ■ THE LINQ TO XML API 221
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.
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.
Listing 7-38. 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.
Table 7-2. The LoadOptions Enumeration
Option Description
LoadOptions.None Use this option to specify that no load options are to
be used.
LoadOptions.PreserveWhitespace Use this option to preserve the whitespace in the XML
source, such as blank lines.
LoadOptions.SetLineInfo Use this option so that you may obtain the line and
position of any object inheriting from XObject by
using the IXmlLineInfo interface.
LoadOptions.SetBaseUri Use this option so that you may obtain the base URI of any
object inheriting from XObject.
Rattz_789-3C07.fm Page 221 Tuesday, October 23, 2007 4:37 PM
222 CHAPTER 7 ■ THE LINQ TO XML API
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.
Listing 7-39. 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:
Rattz_789-3C07.fm Page 222 Tuesday, October 23, 2007 4:37 PM