Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 21 INTRODUCTION TO LINQ

Creating, Saving, Loading, and Displaying an XML Document

The best way to demonstrate the simplicity and usage of the XML API is to show simple code samples. For example, the following code shows how simple it is to perform several of the important tasks required when working with XML.

It starts by creating a simple XML tree consisting of a node called Employees, with two subnodes containing the names of two employees. Notice the following about the code:

The tree is created with a single statement that creates all the nested elements in place in the tree. This is called functional construction.

Each element is created in place using an object creation expression, using the constructor of the type of the node.

After creating the tree, the code saves it to a file called EmployeesFile.xml, using XDocument’s Save method. It then reads the XML tree back from the file using XDocument’s static Load method and assigns the tree to a new XDocument object. Finally, it uses WriteLine to display the structure of the tree held by the new XDocument object.

using System;

 

 

using System.Xml.Linq;

// Required namespace

class Program {

 

 

static void Main( ) {

 

 

XDocument employees1 =

 

 

new XDocument(

// Create the XML document.

new XElement("Employees",

// Create the root element.

new XElement("Name", "Bob Smith"),

// Create element

new XElement("Name", "Sally Jones")

// Create element

)

 

 

);

 

 

employees1.Save("EmployeesFile.xml");

 

// Save to a file

// Load the saved document into a new variable.

XDocument employees2 = XDocument.Load("EmployeesFile.xml");

Static method

Console.WriteLine(employees2);

// Display document

}

 

}

 

This code produces the following output:

<Employees>

<Name>Bob Smith</Name> <Name>Sally Jones</Name>

</Employees>

579

CHAPTER 21 INTRODUCTION TO LINQ

Creating an XML Tree

In the previous example, you saw that you can create an XML document in-memory by using constructors for XDocument and XElement. In the case of both constructors

The first parameter is the name of the object.

The second and following parameters contain the nodes of the XML tree. The second parameter of the constructor is a params parameter, and so can have any number of parameters.

For example, the following code produces an XML tree and displays it using the Console.WriteLine method:

using System;

 

using System.Xml.Linq;

// This namespace is required.

class Program

 

{

 

static void Main( ) {

 

XDocument employeeDoc =

 

new XDocument(

// Create the document.

new XElement("Employees",

// Create the root element.

new XElement("Employee",

// First employee element

new XElement("Name", "Bob Smith"),

new XElement("PhoneNumber", "408-555-1000") ),

new XElement("Employee",

// Second employee element

new XElement("Name", "Sally

Jones"),

new XElement("PhoneNumber",

"415-555-2000"),

new XElement("PhoneNumber",

"415-555-2001") )

)

 

 

);

 

 

Console.WriteLine(employeeDoc);

// Displays the document

}

}

This code produces the following output:

<Employees>

<Employee>

<Name>Bob Smith</Name> <PhoneNumber>408-555-1000</PhoneNumber>

</Employee>

<Employee>

<Name>Sally Jones</Name> <PhoneNumber>415-555-2000</PhoneNumber> <PhoneNumber>415-555-2001</PhoneNumber>

</Employee>

</Employees>

580

CHAPTER 21 INTRODUCTION TO LINQ

Using Values from the XML Tree

The power of XML becomes evident when you traverse an XML tree and retrieve or modify values. Table 21-2 shows the main methods used for retrieving data.

Table 21-2. Methods for Querying XML

Method Name

Class

Return Type

Description

Nodes

Xdocument

IEnumerable<object>

Returns all the children of the current

 

XElement

 

node, regardless of their type

 

 

 

Elements

Xdocument

IEnumerable<XElement>

Returns all the current node’s

 

XElement

 

XElement child nodes or all the child

 

 

nodes with a specific name

 

 

 

Element

Xdocument

XElement

Returns the current node’s first

 

XElement

 

XElement child node or the first child

 

 

node with a specific name

 

 

 

Descendants

XElement

IEnumerable<XElement>

Returns all the descendant XElement

 

 

 

nodes or all the descendant XElement

 

 

 

nodes with a specific name,

 

 

 

regardless of their level of nesting

 

 

 

below the current node

DescendantsAndSelf

XElement

IEnumerable<XElement>

Same as Descendants but also

 

 

 

includes the current node

Ancestors

XElement

IEnumerable<XElement>

Returns all the ancestor XElement

 

 

 

nodes or all the ancestor XElement

 

 

 

nodes above the current node that

 

 

 

have a specific name

AncestorsAndSelf

XElement

IEnumerable<XElement>

Same as Ancestors but also includes

 

 

 

the current node

Parent

XElement

XElement

Returns the parent node of the

 

 

 

current node

 

 

 

 

581

CHAPTER 21 INTRODUCTION TO LINQ

Some of the important things to know about the methods in Table 21-2 are the following:

Nodes: The Nodes method returns an object of type IEnumerable<object>, because the nodes returned might be of different types, such as XElement, XComment, and so on. You can use the type parameterized method OfType<type> to specify what type of nodes to return. For example, the following line of code retrieves only the XComment nodes:

IEnumerable<XComment> comments = xd.Nodes().OfType<XComment>();

Elements: Since retrieving XElements is such a common requirement, there is a shortcut for expression Nodes().OfType<XElement>()—the Elements method.

Using the Elements method with no parameters returns all the child XElements.

Using the Elements method with a single name parameter returns only the child XElements with that name. For example, the following line of code returns all the child XElement nodes with the name PhoneNumber.

IEnumerable<XElement> empPhones = emp.Elements("PhoneNumber");

Element: This method retrieves just the first child XElement of the current node. Like the

Elements method, it can be called with either one or no parameters. With no parameters, it gets the first child XElement node. With a single name parameter, it gets the first child XElement node of that name.

Descendants and Ancestors: These methods work like the Elements and Parent methods, but instead of returning the immediate child elements or parent element, they include the elements below or above the current node, regardless of the difference in nesting level.

582

CHAPTER 21 INTRODUCTION TO LINQ

The following code illustrates the Element and Elements methods:

using System;

using System.Collections.Generic; using System.Xml.Linq;

class Program {

static void Main( ) { XDocument employeeDoc =

new XDocument(

new XElement("Employees",

new XElement("Employee",

 

new XElement("Name", "Bob Smith"),

new XElement("PhoneNumber",

"408-555-1000")),

new XElement("Employee",

 

new XElement("Name", "Sally

Jones"),

new XElement("PhoneNumber",

"415-555-2000"),

new XElement("PhoneNumber",

"415-555-2001"))

 

)

 

 

);

Get first child XElement named "Employees"

 

 

 

XElement root = employeeDoc.Element("Employees");

IEnumerable<XElement> employees = root.Elements();

foreach (XElement emp in employees)

{

Get first child XElement named "Name"

 

 

 

XElement empNameNode = emp.Element("Name");

Console.WriteLine(empNameNode.Value);

Get all child elements named "PhoneNumber"

IEnumerable<XElement> empPhones = emp.Elements("PhoneNumber"); foreach (XElement phone in empPhones)

Console.WriteLine(" {0}", phone.Value);

}

}

}

This code produces the following output:

Bob Smith 408-555-1000

Sally Jones 415-555-2000 415-555-2001

583

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]