Tải bản đầy đủ (.pdf) (108 trang)

mcts 70-562 Microsoft .NET Framework 3.5, ASP.NET Application Development phần 6 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.37 MB, 108 trang )

Lesson 3: Working with XML Data CHAPTER 7 511
System.Text.Encoding.UTF8)

With xmlWriter
.Formatting = Formatting.Indented
.Indentation = 5

.WriteStartDocument()
.WriteComment("XmlTextWriter Test Date: " & _
DateTime.Now.ToShortDateString())

.WriteStartElement("EmployeeList")

'New Employee
.WriteStartElement("Employee")
.WriteAttributeString("EmpID", "1")
.WriteAttributeString("LastName", "JoeLast")
.WriteAttributeString("FirstName", "Joe")
.WriteAttributeString("Salary", XmlConvert.ToString(50000))

.WriteElementString("HireDate", _
XmlConvert.ToString(#1/1/2003#, _
XmlDateTimeSerializationMode.Unspecified))

.WriteStartElement("Address")
.WriteElementString("Street1", "123 MyStreet")
.WriteElementString("Street2", "")
.WriteElementString("City", "MyCity")
.WriteElementString("State", "OH")
.WriteElementString("ZipCode", "12345")


'Address
.WriteEndElement()
'Employee
.WriteEndElement()

'New Employee
.WriteStartElement("Employee")
.WriteAttributeString("EmpID", "2")
.WriteAttributeString("LastName", "MaryLast")
.WriteAttributeString("FirstName", "Mary")
.WriteAttributeString("Salary", XmlConvert.ToString(40000))

.WriteElementString("HireDate", _
XmlConvert.ToString(#1/2/2003#, _
XmlDateTimeSerializationMode.Unspecified))

5 1 2 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
.WriteStartElement("Address")
.WriteElementString("Street1", "234 MyStreet")
.WriteElementString("Street2", "")
.WriteElementString("City", "MyCity")
.WriteElementString("State", "OH")
.WriteElementString("ZipCode", "23456")

'Address
.WriteEndElement()
'Employee
.WriteEndElement()

'EmployeeList

.WriteEndElement()
.Close()
End With
Response.Redirect("EmployeeList.xml")
End Sub

//C#
protected void Button10_Click(object sender, EventArgs e)
{
XmlTextWriter xmlWriter = new
XmlTextWriter(MapPath("EmployeeList.xml"),
System.Text.Encoding.UTF8);

xmlWriter.Formatting = Formatting.Indented;
xmlWriter.Indentation = 5;

xmlWriter.WriteStartDocument();
xmlWriter.WriteComment("XmlTextWriter Test Date: " +
DateTime.Now.ToShortDateString());

xmlWriter.WriteStartElement("EmployeeList");

//New Employee
xmlWriter.WriteStartElement("Employee");
xmlWriter.WriteAttributeString("EmpID", "1");
xmlWriter.WriteAttributeString("LastName", "JoeLast");
xmlWriter.WriteAttributeString("FirstName", "Joe");
xmlWriter.WriteAttributeString("Salary", XmlConvert.ToString(50000));

xmlWriter.WriteElementString("HireDate",

XmlConvert.ToString(DateTime.Parse("1/1/2003"),
XmlDateTimeSerializationMode.Unspecified));

Lesson 3: Working with XML Data CHAPTER 7 513
xmlWriter.WriteStartElement("Address");
xmlWriter.WriteElementString("Street1", "123 MyStreet");
xmlWriter.WriteElementString("Street2", "");
xmlWriter.WriteElementString("City", "MyCity");
xmlWriter.WriteElementString("State", "OH");
xmlWriter.WriteElementString("ZipCode", "12345");

//Address
xmlWriter.WriteEndElement();
//Employee
xmlWriter.WriteEndElement();

//New Employee
xmlWriter.WriteStartElement("Employee");
xmlWriter.WriteAttributeString("EmpID", "2");
xmlWriter.WriteAttributeString("LastName", "MaryLast");
xmlWriter.WriteAttributeString("FirstName", "Mary");
xmlWriter.WriteAttributeString("Salary", XmlConvert.ToString(40000));

xmlWriter.WriteElementString("HireDate",
XmlConvert.ToString(DateTime.Parse("1/2/2003"),
XmlDateTimeSerializationMode.Unspecified));

xmlWriter.WriteStartElement("Address");
xmlWriter.WriteElementString("Street1", "234 MyStreet");
xmlWriter.WriteElementString("Street2", "");

xmlWriter.WriteElementString("City", "MyCity");
xmlWriter.WriteElementString("State", "OH");
xmlWriter.WriteElementString("ZipCode", "23456");

//Address
xmlWriter.WriteEndElement();
//Employee
xmlWriter.WriteEndElement();

//EmployeeList
xmlWriter.WriteEndElement();
xmlWriter.Close();

Response.Redirect("EmployeeList.xml");
}
This code starts by opening the file as part of the constructor for the XmlTextWriter. The
constructor also expects an encoding type. Because an argument is required, passing Nothing
causes the encoding type to be UTF-8, which is the same as the value that is explicitly being
passed. The following is the EmployeeList.xml file that is created:
5 1 4 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
<?xml version="1.0" encoding="utf-8"?>
<! XmlTextWriter Test Date: 8/16/2006 >
<EmployeeList>
<Employee EmpID="1" LastName="JoeLast" FirstName="Joe" Salary="50000">
<HireDate>2003-01-01T00:00:00</HireDate>
<Address>
<Street1>123 MyStreet</Street1>
<Street2 />
<City>MyCity</City>
<State>OH</State>

<ZipCode>12345</ZipCode>
</Address>
</Employee>
<Employee EmpID="2" LastName="MaryLast" FirstName="Mary" Salary="40000">
<HireDate>2003-01-02T00:00:00</HireDate>
<Address>
<Street1>234 MyStreet</Street1>
<Street2 />
<City>MyCity</City>
<State>OH</State>
<ZipCode>23456</ZipCode>
</Address>
</Employee>
</EmployeeList>
There are many statements that are doing nothing more than writing to the xmlWriter.
Typing time is saved in the Visual Basic code by the use of the With xmlWriter statement,
which allows a simple dot to be typed to represent the xmlWriter object.
The XmlTextWriter handles the formatting of the document by setting the Formatting and
Indentation properties.
The WriteStartDocument method writes the XML declaration to the file. The WriteComment
method writes a comment to the file.
When writing elements, you can use either the WriteStartElement method or the Write-
ElementString method. The WriteStartElement method only writes the starting element but
keeps track of the nesting level and adds new elements inside this element. The element is
completed when a call is made to the WriteEndElement method. The WriteElementString
method simply writes a closed element to the file.
The WriteAttribute method takes a name and value pair and writes the attribute into the
current open element.
When writing is complete, the Close method must be called to avoid losing data. The file is
then saved.

Lesson 3: Working with XML Data CHAPTER 7 515
Reading a File Using the XmlTextReader
The XmlTextReader is used to read an XML file node by node. The reader provides forward-
only, noncaching access to an XML data stream. The reader is ideal for use when there is a
possibility that the information that is desired is near the top of the XML file and the file is
large. If random access is required, use the XPathNavigator class or the XmlDocument class.
The following code reads the XML file that was created in the previous example and displays
information about each node:
'VB
Protected Sub Button11_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button11.Click
lbl = GetLabel(275, 20)
Dim xmlReader As New _
XmlTextReader(MapPath("EmployeeList.xml"))

Do While xmlReader.Read()

Select Case xmlReader.NodeType
Case XmlNodeType.XmlDeclaration, _
XmlNodeType.Element, _
XmlNodeType.Comment
Dim s As String
s = String.Format("{0}: {1} = {2}<br>", _
xmlReader.NodeType, _
xmlReader.Name, _
xmlReader.Value)
lbl.Text += s
Case XmlNodeType.Text
Dim s As String
s = String.Format(" - Value: {0}<br>", _

xmlReader.Value)
lbl.Text += s
End Select

If xmlReader.HasAttributes Then
Do While xmlReader.MoveToNextAttribute()
Dim s As String
s = String.Format(" - Attribute: {0} = {1}<br>", _
xmlReader.Name, xmlReader.Value)
lbl.Text += s
Loop
End If
Loop
xmlReader.Close()
End Sub


Lesson 3: Working with XML Data CHAPTER 7 517
This code opens the EmployeeList file, and then performs a simple loop, reading one ele-
ment at a time until finished. For each node that is read, a check is made on the NodeType,
and the node information is printed. When a node is read, its corresponding attributes are
read as well. A check is made to see if the node has attributes, and they are displayed.
Modifying an XML Document
Once the XmlDocument object is loaded, you can easily add and remove nodes. When
removing a node, you simply need to locate the node and delete it from its parent. When
adding a node, you need to create the node, search for the appropriate location into which to
insert the node, and insert the node. The following code deletes an existing node and adds a
new node:
'VB
Protected Sub Button12_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Button12.Click

lbl = GetLabel(275, 20)

'Declare and load new XmlDocument
Dim xmlDoc As New XmlDocument()
xmlDoc.Load(MapPath("XmlSample.xml"))

'delete a node
Dim node As XmlNode
node = xmlDoc.SelectSingleNode("//myChild[@ChildID='ref-3']")
node.ParentNode.RemoveChild(node)

'create a node and add it
Dim newElement as XmlElement = _
xmlDoc.CreateElement("myNewElement")
node = xmlDoc.SelectSingleNode("//myChild[@ChildID='ref-1']")
node.ParentNode.InsertAfter(newElement, node)
xmlDoc.Save(MapPath("XmlSampleModified.xml"))
Response.Redirect("XmlSampleModified.xml")
End Sub

//C#
protected void Button12_Click(object sender, EventArgs e)
{
lbl = GetLabel(275, 20);

//Declare and load new XmlDocument
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(MapPath("XmlSample.xml"));


5 1 8 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
//delete a node
XmlNode node;
node = xmlDoc.SelectSingleNode("//myChild[@ChildID='ref-3']");
node.ParentNode.RemoveChild(node);

//create a node and add it
XmlElement newElement =
xmlDoc.CreateElement("myNewElement");
node = xmlDoc.SelectSingleNode("//myChild[@ChildID='ref-1']");
node.ParentNode.InsertAfter(newElement, node);
xmlDoc.Save(MapPath("XmlSampleModified.xml"));
Response.Redirect("XmlSampleModified.xml");
}
To delete a node, use the SelectSingleNode method to locate the node to delete. After the
node is located, the node can be removed from its parent by using the ParentNode property’s
RemoveChild method.
To add a node, execute the CreateElement method on the XmlDocument object. Next, the
insert location is searched and the ParentNode property’s InsertAfter method is used to insert
the new node.
Validating XML Documents
An important element to exchanging documents between disparate systems is the ability to
define the structure of an XML document and then validate the XML document against its
defined structure. The .NET Framework offers the ability to perform validation against a DTD
or schema. Earlier versions of the .NET Framework used the XmlValidatingReader object to
perform validation, but this object is now obsolete. Instead, this section explores XML docu-
ment validation using the XmlReader class.
The XmlReader class performs forward-only reading and validation of a stream of XML.
The XmlReader class contains a Create method that can be passed as a string or a stream,

as well as an XmlReaderSettings object. To perform validation, the XmlReaderSettings object
must be created and its properties set to perform validation. In the next example, the files
XmlSample.xml and XmlBadSample.xml are validated using the following code:
'VB
Protected Sub Button13_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button13.Click
lbl = GetLabel(275, 20)
If ValidateDocument(MapPath("XmlSample.xml")) Then
lbl.Text += "Valid Document<br />"
Else
lbl.Text += "Invalid Document<br />"
End If
End Sub

Lesson 3: Working with XML Data CHAPTER 7 519
Protected Sub Button14_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button14.Click
lbl = GetLabel(275, 20)
If ValidateDocument(MapPath("XmlBadSample.xml")) Then
lbl.Text += "Valid Document<br />"
Else
lbl.Text += "Invalid Document<br />"
End If
End Sub

Public Function ValidateDocument(ByVal fileName As String) _
As Boolean
Dim xmlSet As New XmlReaderSettings()
xmlSet.ValidationType = ValidationType.DTD
xmlSet.ProhibitDtd = False

Dim vr As XmlReader = XmlReader.Create( _
fileName, xmlSet)

Dim xd As New XmlDocument()
Try
xd.Load(vr)
Return True
Catch ex As Exception
lbl.Text += ex.Message + "<br />"
Return False
Finally
vr.Close()
End Try
End Function

//C#
protected void Button13_Click(object sender, EventArgs e)
{
lbl = GetLabel(275, 20);
if (ValidateDocument(MapPath("XmlSample.xml")))
{
lbl.Text += "Valid Document<br />";
}
else
{
lbl.Text += "Invalid Document<br />";
}
}

protected void Button14_Click(object sender, EventArgs e)

{
5 2 0 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
lbl = GetLabel(275, 20);
if (ValidateDocument(MapPath("XmlBadSample.xml")))
{
lbl.Text += "Valid Document<br />";
}
else
{
lbl.Text += "Invalid Document<br />";
}
}

private bool ValidateDocument(string fileName)
{
XmlReaderSettings xmlSet = new XmlReaderSettings();
xmlSet.ValidationType = ValidationType.DTD;
xmlSet.ProhibitDtd = false;
XmlReader vr = XmlReader.Create(fileName, xmlSet);
XmlDocument xd = new XmlDocument();
try
{
xd.Load(vr);
return true;
}
catch (Exception ex)
{
lbl.Text += ex.Message + "<br />";
return false;
}

finally
{
vr.Close();
}
}
The XmlBadSample.xml file is as follows:
XML File: XmlBadSample.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE myRoot [
<!ELEMENT myRoot ANY>
<!ELEMENT myChild ANY>
<!ELEMENT myGrandChild EMPTY>
<!ATTLIST myChild
ChildID ID #REQUIRED
>
]>
<myRoot>
Lesson 3: Working with XML Data CHAPTER 7 521
<myChild ChildID="ref-1">
<myGrandChild/>
<myGrandChild/>
<myGrandChild/>
</myChild>
<myChild ChildID="ref-2">
<myGrandChild/>
<myGrandChild/>
<myGrandChild>this is malformed</myGrandChild>
</myChild>
<myChild ChildID="ref-3">
<myGrandChild/>

<myGrandChild/>
<myGrandChild/>
</myChild>
<myChild ChildID="ref-4">
<myGrandChild/>
<myGrandChild/>
<myGrandChild/>
</myChild>
</myRoot>
This code simply opens the XML fi le with an XmlReader, and, while the XmlDocument is
being read, the document is being validated. Because this code has an embedded DTD, the
document is validated.
The DTD states that the myGrandChild element must be empty, but one of the myGrand-
Child elements of myChild ref-1 has a myGrandChild element containing the words, this is
malformed. This causes an error. Attempts to read from the XmlReader when valid should
always be within a Try-Catch block to catch possible validation exceptions.
Quick Check
1. What method can you execute to locate a single XML node by its tag name?
2. What method can you use to search for all elements that have a specifi c tag
name and retrieve the results as an XmlNodeList?
3. What object should you use to perform XPath queries on large XML documents?
Quick Check Answers
1. You can execute SelectSingleNode.
2. You can use GetElementsByTagName or SelectNodes.
3. You should use XPathNavigator.
Quick Check
1
. What method can you execute to locate a single XML node by its tag name?
2
. What method can you use to search for all elements that have a specifi c tag

name and retrieve the results as an
XmlNodeList
?
3
. What object should you use to perform XPath queries on large XML documents?
Quick Check Answers
1
. You can execute
SelectSingleNode
.
2
. You can use
GetElementsByTagName
or
SelectNodes
.
3
. You should use
XPathNavigator
.
XPathNavigator.XPathNavigator
1
2
3
1
2
3
5 2 2 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
Using LINQ to XML
Another way to work with XML in the .NET Framework is through the LINQ to XML classes

found inside the System.Xml.Linq namespace. These classes provide an easier, faster, and
richer experience when working with XML data. In addition, they leverage LINQ to ensure a
consistent query model when searching for data embedded in XML. With LINQ to XML, you
can do everything you’ve seen thus far, including loading XML from a file, serializing it to
streams and files, querying against it, validating, manipulating it in memory, and much more.
In fact, many of the LINQ to XML classes use the other objects discussed previously as their
internal means of working with data (such as the XmlReader class used to read XML).
The LINQ to XML Classes
The LINQ to XML classes are accessible through the System.Xml.Linq namespace. There are
many classes here. However, the key class with which you will work is the XElement class,
which provides the ability to easily create XML elements, load them from files, query against
them, and write them back out or send them across the wire. Figure 7-19 shows a high-level
view of the objects that are defined inside the Xml.Linq namespace.
FIGURE 7-19 The classes of LINQ to XML (System.Xml.Linq namespace)
The sections that follow provide an overview of working with XElement. However, it is im-
portant to have an understanding of the other classes that make up LINQ to XML. Table 7-6
presents the classes shown in Figure 7-19 and provides a description of each.
Lesson 3: Working with XML Data CHAPTER 7 523
TABLE 7-6 The LINQ to XML Classes Inside the System.Xml.Linq Namespace
CLASS DESCRIPTION
XAttribute Represents a class for working with XML attributes. You can
create a new instance of this class that includes a name and
value. You can use the XAttribute class to add attributes to
an XElement.
The XAttribute class is also used for functional XML pro-
gramming (described later) when defining trees.
XCData Represents a CDATA string section of an XML element or
document. This class derives from XText.
XComment Represents a comment in an XML structure. The XComment
class can be a child of an XElement or a sibling of the root

node in an XDocument.
XContainer Represents the base class for XElement and XDocument.
XDeclaration Represents an XML declaration including XML version and
encoding information.
XDocument Represents a valid XML document. This class contains the
full document. Many times you only need to work with
elements of a document. In this case, the XElement is the
preferred class. The XDocument exists for when you need to
work with an entire structure of an XML document (includ-
ing elements, comments, declarations, and so on).
XDocumentType Represents an XML DTD used for validating XML trees and
supplying default attributes.
XElement Represents an XML element. This is the core class of LINQ to
XML. You can use this class to declare, load, and work with
portions of an XML structure.
XName Represents names of elements and attributes.
XNamespace Represents a namespace for XElement or XAttribute.
Namespaces are part of XName.
XNode Represents the nodes of an XML tree. This is a base class for
XText, XContainer, XComment, XProcessingInstruction, and
XDocumentType.
XNodeDocumentOrder-
Compare
Represents features used to compare nodes for document
order.
XNodeEqualityComparer Represents features used to compare nodes for equality.
XObject Represents a base class used by XNode and XAttribute. Pro-
vides base event functionality for these classes.
5 2 4 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
CLASS DESCRIPTION

XObjectChange Represents the event type for events raised by classes that
use XObject.
XObjectChangeEventArgs Represents the data for the Changing and Changed events.
XProcessingInstruction Represents an XML processing instruction.
XText Represents a text node in XML.
Loading an XML Tree
To work with LINQ to XML, you need to get XML into memory. This means loading (or pars-
ing) it from a file, string, or XmlReader. You parse XML data into an XElement (or XDocument).
As an example, if you have a file that contains employee data, you can read that file by calling
the Load method of XElement. The following code shows this feature. Notice the call to Server.
MapPath to get the path to the Employee.xml file stored in the root of the Web site.
'VB
Dim xmlFile As String = Server.MapPath("/DataSamples") & "\employee.xml"
Dim employees As XElement = XElement.Load(xmlFile)

//C#
string xmlFile = Server.MapPath(@"/DataSamples") + @"\employee.xml";
XElement employees = XElement.Load(xmlFile);
The XElement class also contains the Parse method, which is used to load XML from a
string. You simply pass the string as a parameter to the static Parse method. This is great if
your XML is already in a string. However, if you are defining XML in your code, you should do
so functionally and not as a string, as using the functional approach is faster. This is discussed
further in the section “Creating an XML Tree with XElement” later in this lesson.
Writing LINQ Queries Against XML Trees
The queries you write with LINQ to XML can be seen as similar to XPath and XQuery. Howev-
er, they use the standard LINQ notation. This ensures a single, consistent query model across
different types of data. You write LINQ to XML queries in a similar way as querying against
a DataSet. This is because the XML data, like the DataSet, is an in-memory store. In addition,
there is not an O/R map as in LINQ to SQL.
As an example, suppose you have an XML file that contains employees. The XML file might

look like this:
<?xml version="1.0" standalone="yes"?>
<Employees>
<Employee>
<id>A-C71970F</id>
<FirstName>Aria</FirstName>
Lesson 3: Working with XML Data CHAPTER 7 525
<LastName>Cruz</LastName>
<Salary>15</Salary>
</Employee>
<Employee>
<id>A-R89858F</id>
<FirstName>Annette</FirstName>
<LastName>Roulet</LastName>
<Salary>24</Salary>
</Employee>
<Employee>
<id>CFH28514M</id>
<FirstName>Carlos</FirstName>
<LastName>Hernadez</LastName>
<Salary>18</Salary>
</Employee>
<Employee>
<id>M-L67958F</id>
<FirstName>Maria</FirstName>
<LastName>Larsson</LastName>
<Salary>17</Salary>
</Employee>
<Employee>
<id>VPA30890F</id>

<FirstName>Victoria</FirstName>
<LastName>Ashworth</LastName>
<Salary>21</Salary>
</Employee>
</Employees>
Suppose you need to write a query against this XML that returns all employees whose
salary is greater than 20. You would start by first loading the XML into memory as an XEle-
ment instance. You could then define a LINQ query against the XElement to return employee
elements that contain a Salary element with a value greater than 20. The following code
demonstrates this query and writes the results out to a Web page:
'VB
Dim xmlFile As String = Server.MapPath("/DataSamples") & "\employee.xml"
Dim employees As XElement = XElement.Load(xmlFile)

Dim query As IEnumerable(Of XElement) = _
From emp In employees.<Employee> _
Where CType(emp.Element("Salary"), Integer) > 20 _
Select emp

For Each emp As XElement In query
Response.Write(emp.Element("FirstName").ToString() & ", ")
Response.Write(emp.Element("LastName").ToString() & "<br />")
5 2 6 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
Response.Write(emp.Element("Salary").ToString() & "<br /><br />")
Next

//C#
string xmlFile = Server.MapPath(@"/DataSamples") + @"\employee.xml";
XElement employees = XElement.Load(xmlFile);


IEnumerable<XElement> query =
from emp in employees.Elements("Employee")
where (int)emp.Element("Salary") > 20
select emp;

foreach (XElement emp in query)
{
Response.Write(emp.Element("FirstName").ToString() + ", ");
Response.Write(emp.Element("LastName").ToString() + "<br />");
Response.Write(emp.Element("Salary").ToString() + "<br /><br />");
}
Creating an XML Tree with XElement
LINQ to XML also adds the ability to functionally define XML in your code. This means creat-
ing an XML XElement object tree in code (and not just as a parsed string). This can make your
code easier to read and easier to write. In fact, Visual Basic developers can actually write the
XML as angle-bracketed items with intelligent coloring in the IDE. C# developers, on the other
hand, still have to call object constructors. However, they also have an easy way to build XML
trees in code.
As an example, suppose you wish to define an XElement that represents a list of employ-
ees. You might also want to define a few child elements that represent actual employees and
their data. You could do so by simply nesting calls to the new XElement constructor, which
takes a parameter array as a value. For Visual Basic developers, this is abstracted further and
you can simply write XML in your code. The following shows an example:
'VB
Dim employees As XElement = _
<Employees>
<Employee>
<id>MFS52347M</id>
<FirstName>Martin</FirstName>
<LastName>Sommer</LastName>

<Salary>15</Salary>
</Employee>
</Employees>

//C#
XElement employees =
Lesson 3: Working with XML Data CHAPTER 7 527
new XElement("Employees",
new XElement("Employee",
new XElement("id", "MFS52347M"),
new XElement("FirstName", "Martin"),
new XElement("LastName", "Sommer"),
new XElement("Salary", 15)
)
);
To add further power to defining XML, you can also embed queries as one of the param-
eters to building XElements. The result of these queries will get added to the XML stream.
For example, consider the previous employees definition. Suppose you wish to add all the
employees from the Employee.xml file to this list. You could do so in the XElement definition
by adding a query at the end of the first employee definition. The following code shows an
example. Notice the statement
from emp in empFile.Elements(); this is the call to the query.
'VB
Dim xmlFile As String = Server.MapPath("/DataSamples") & "\employee.xml"
Dim empFile As XElement = XElement.Load(xmlFile)

Dim employees As XElement = _
<Employees>
<Employee>
<id>MFS52347M</id>

<FirstName>Martin</FirstName>
<LastName>Sommer</LastName>
<Salary>15</Salary>
</Employee>
<%= From emp In empFile.Elements() _
Select emp %>
</Employees>

For Each emp As XElement In employees.Elements
Response.Write(emp.Element("FirstName").ToString() & ", ")
Response.Write(emp.Element("LastName").ToString() & "<br />")
Response.Write(emp.Element("Salary").ToString() & "<br /><br />")
Next

//C#
string xmlFile = Server.MapPath(@"/DataSamples") + @"\employee.xml";
XElement empFile = XElement.Load(xmlFile);

XElement employees =
new XElement("Employees",
new XElement("Employee",
new XElement("id", "MFS52347M"),
5 2 8 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
new XElement("FirstName", "Martin"),
new XElement("LastName", "Sommer"),
new XElement("Salary", 15)
),
from emp in empFile.Elements()
select emp
);

foreach (XElement emp in employees.Elements())
{
Response.Write(emp.Element("FirstName").ToString() + ", ");
Response.Write(emp.Element("LastName").ToString() + "<br />");
Response.Write(emp.Element("Salary").ToString() + "<br /><br />");
}
Lab Working with XML Data
In this lab, you work with XML data to display a subset of an XML fi le in a GridView control,
using the XmlDataSource and an XSLT fi le.
If you encounter a problem completing an exercise, the completed projects are available in
the samples installed from the companion CD in the Code folder.
ExErcisE 1 Create the Web Site and the XML Files
In this exercise, you create the Web site and XML fi le.
1. Open Visual Studio; create a new Web site called XmlData using your preferred pro-
gramming language.
2. In Solution Explorer, right-click the App_Data folder and select Add New Item. Select
XML File, name the fi le ProductList.xml, and click Add.
3. In the XML fi le, add the following:
<?xml version="1.0" encoding="utf-8" ?>
<ProductList>
<Product Id="1A59B" Department="Sporting Goods" Name="Baseball" Price="3.00"
/>
<Product Id="9B25T" Department="Sporting Goods" Name="Tennis Racket"
Price="40.00" />
<Product Id="3H13R" Department="Sporting Goods" Name="Golf Clubs"
Price="179.00" />
<Product Id="7D67A" Department="Clothing" Name="Shirt" Price="12.00" />
<Product Id="4T21N" Department="Clothing" Name="Jacket" Price="45.00" />
</ProductList>
<?xml version="1.0" encoding="utf-8" ?>

<ProductList>
<Product Id="1A59B" Department="Sporting Goods" Name="Baseball" Price="3.00"
/>
<Product Id="9B25T" Department="Sporting Goods" Name="Tennis Racket"
Price="40.00" />
<Product Id="3H13R" Department="Sporting Goods" Name="Golf Clubs"
Price="179.00" />
<Product Id="7D67A" Department="Clothing" Name="Shirt" Price="12.00" />
<Product Id="4T21N" Department="Clothing" Name="Jacket" Price="45.00" />
</ProductList>
Lesson 3: Working with XML Data CHAPTER 7 529
4. Open the Default.aspx page. In Design view, drag a DetailsView control onto the page
and size it wide enough to display the car information.
5. Click the smart tag in the upper right corner of the DetailsView control to display the
DetailsView Tasks window.
Click the Auto Format link and select Professional.
6. Click the Choose Data Source drop-down list and select New Data Source to start
the Data Source Confi guration Wizard. For the data source type, select XML File and
click OK.
7. On the Confi gure Data Source page, click Browse next to the Data File text box and
browse to the ProductList.xml fi le in the App_Data folder.
8. Click OK.
9. Select the Enable Paging option in the DetailsView tasks window. Confi guration of the
DetailsView is complete.
10. Run the Web page. Notice that the data is retrieved and displayed.
Lesson Summary
n
XML documents can be accessed using the DOM.
n
The XPathNavigator uses a cursor model and XPath queries to provide read-only, ran-

dom access to the data.
n
The XmlReader provides an object for validating against DTD, XDR, or XSD by setting
the XmlReaderSettings object properties.
n
LINQ to XML uses the XElement class to load XML data, write LINQ queries against it,
and write the data back if need be. You can also functionally defi ne XML in your code
using LINQ to XML.
Lesson Review
You can use the following questions to test your knowledge of the information in Lesson 3,
“Working with XML Data.” The questions are also available on the companion CD if you prefer
to review them in electronic form.
NOTE ANSWERS
Answers to these questions and explanations of why each answer choice is right or wrong
are located in the “Answers” section at the end of the book.
NOTE
ANSWERS
Answers to these questions and explanations of why each answer choice is right or wrong
are located in the “Answers” section at the end of the book.
5 3 0 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
1. Which class can be used to create an XML document from scratch?
A. XmlConvert
B. XmlDocument
C. XmlNew
D. XmlSettings
2. Which class can be used to perform data type conversion between .NET Framework
data types and XML types?
A. XmlType
B. XmlCast
C. XmlConvert

D. XmlSettings
3. You are writing a function that accepts a string as a parameter. The string data will be
sent to the function in the form of XML. You need to write LINQ to XML code to query
this XML and process it. What steps should you take? (Choose all that apply.)
A. Use the XElement.Load method to load the XML data into a new XElement.
B. Use the XElement.Parse method to load the XML data into a new XElement.
C. Define a query variable of type IEnumerable<> where the generic type is set to
XElement.
D. Define a query variable of type IEnumerable<> where the generic type is set to the
value of the string parameter passed to the function.
Chapter Review CHAPTER 7 531
Chapter Review
To further practice and reinforce the skills you learned in this chapter, you can perform the
following tasks:
n
Review the chapter summary.
n
Complete the case scenarios. These scenarios set up real-world situations involving the
topics of this chapter and ask you to create solutions.
n
Complete the suggested practices.
n
Take a practice test.
Chapter Summary
n
ADO.NET provides disconnected objects like the DataTable and DataSet that can be
used independently from a database connection. In addition, LINQ to DataSet provides
a query processing engine for data represented in the disconnected objects DataSet
and DataTable.
n

ADO.NET provides connected objects that are provider-specific for SQL, Oracle,
OLEDB, and ODBC. In addition, LINQ to SQL provides a powerful set of features for
programming against SQL Server databases with O/R mapping.
n
ADO.NET provides access to XML files using the classes in the System.Xml namespace.
The LINQ to XML technology allows you to work with XML data using the query fea-
tures of LINQ.
Case Scenarios
In the following case scenarios, you will apply what you’ve learned in this chapter. If you have
difficulty completing this work, review the material in this chapter before beginning the next
chapter. You can find answers to these questions in the “Answers” section at the end of this
book.
Case Scenario 1: Determining Ways to Update the Database
You are creating a new Web page that allows users to upload expense reports (as XML data).
The expense report data contains general information about the expense report, such as the
employee name and ID, the branch office number, and the week-ending date. The expense
report file also contains information that describes each specific expense. For mileage, this
data includes the date and the mileage amount, and the to and from locations. For entertain-
ment, the data includes the location, the expense amount, and a description of the entertain-
ment expense.
You need to import this data into a SQL database and are looking for options.
5 3 2 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
QUESTIONS
1.
What are some methods of importing this data into the SQL Server database?
Case Scenario 2: Storing a DataSet to a Binary File
Your code populates a DataSet with more than 200,000 DataRows in several related DataT-
ables. You want to store this DataSet object to a file, but you want the file to be as small as
possible.
QUESTIONS

1.
What object would you use to store the data?
2. What settings would you set to serialize the data properly?
Suggested Practices
To help you successfully master the exam objectives presented in this chapter, complete the
following tasks.
Create a Web Page for Updating Database Data
For this task, you should complete all three practices.
n
Practice 1 Create a Web page and add Web server controls to prompt the user for a
percentage increase (or decrease) for the price of the products in your database. Use
the Northwind database, which has a Products table.
n
Practice 2 Add code to open a connection to the database and execute a SQL query
to increase or decrease the UnitPrice of all products based on the value submitted by
the user.
n
Practice 3 Add code to perform the update of the Products table within a SqlTransac-
tion.
Create a Web Page for Editing Disconnected Data
For this task, you should complete the first practice for working with the DataTable objects.
The second practice helps you with LINQ to DataSet.
n
Practice 1 Create a Web page and add a button to create a DataTable that contains a
schema for employees, a button that adds a DataRow into the employees DataTable, a
button that modifies an existing DataRow, and a button that deletes a DataRow.
Suggested Practices CHAPTER 7 533
n
Practice 2 Read the employee data from the pubs database into a DataTable object
and disconnect from the database. Write a LINQ to DataSet query against the Data-

Table to show all employee records where the hire date is greater than 1991. Order the
data by hire date. Bind the results to a GridView control.
Create a Web Page for Editing Connected Data
For this task, you should complete both practices.
n
Practice 1 Create a Web page and add a SqlDataSource configured to read data from
a SQL Server or SQL Server Express Edition database and display the data in a GridView
control.
n
Practice 2 Modify the Web page to enable inserts, updates, and deletions.
Create a Web Page for Working with XML Data
For this task, you should complete the first two practices for working with the standard XML
classes. The third practice can be used for learning more about LINQ to XML.
n
Practice 1 Create a Web page that uses an XmlDataSource to read data from an XML
file and display the data in a GridView control.
n
Practice 2 Modify the Web page to enable inserts, updates, and deletions.
n
Practice 3 Create an XML file using one of the tables in the Pubs database as source
data. You can read this data in as a DataSet and serialize it out as XML. Write a Web
page to load this XML data into an XElement class. Write a LINQ query against this data
and display the results on a Web page.
Create a Web Page for Reading, Modifying, and Writing
XML Data
For this task, you should complete all three practices.
n
Practice 1 Create an XML file that contains a list of products and their prices.
n
Practice 2 Create a Web page and add Web server controls to prompt the user for a

percentage increase (or decrease) for the price of the products in your XML file.
n
Practice 3 Add code to use the XmlReader to read the products file, modify the price,
and then use the XmlWriter to write the data to a file.
5 3 4 CHAPTER 7 Using ADO.NET, XML, and LINQ with ASP.NET
Take a Practice Test
The practice tests on this book’s companion CD offer many options. For example, you can test
yourself on just the content covered in this chapter, or you can test yourself on all the 70-562
certifi cation exam content. You can set up the test so it closely simulates the experience of
taking a certifi cation exam, or you can set it up in study mode so you can look at the correct
answers and explanations after you answer each question.
MORE INFO PRACTICE TESTS
For details about all the practice test options available, see the “How to Use the Practice
Tests” section in this book’s Introduction.
MORE INFO
PRACTICE TESTS
For details about all the practice test options available, see the “How to Use the Practice
Tests” section in this book’s Introduction.

×