Tải bản đầy đủ - 0 (trang)
6-6. Find Elements with an XPath Search

6-6. Find Elements with an XPath Search

Tải bản đầy đủ - 0trang

CHAPTER 6 ■ XML PROCESSING



Solution

Execute an XPath expression using the SelectNodes or SelectSingleNode method of the XmlDocument

class.



How It Works

The XmlNode class defines two methods that perform XPath searches: SelectNodes and SelectSingleNode.

These methods operate on all contained child nodes. Because the XmlDocument inherits from XmlNode,

you can call XmlDocument.SelectNodes to search an entire document.



The Code

For example, consider the following XML document, which represents an order for two items. This

document includes text and numeric data, nested elements, and attributes, and so is a good way to test

simple XPath expressions.







Remarkable Office Supplies







Electronic Protractor

42.99





Invisible Ink

200.25







Basic XPath syntax uses a pathlike notation. For example, the path /Order/Items/Item indicates an

element that is nested inside an element, which in turn is nested in a root

element. This is an absolute path. The following example uses an XPath absolute path to find the name

of every item in an order:

using System;

using System.Xml;

namespace Apress.VisualCSharpRecipes.Chapter06

{

public class Recipe06_06

{

private static void Main()

{



275



www.it-ebooks.info



CHAPTER 6 ■ XML PROCESSING



// Load the document.

XmlDocument doc = new XmlDocument();

doc.Load(@"..\..\orders.xml");

// Retrieve the name of every item.

// This could not be accomplished as easily with the

// GetElementsByTagName method, because Name elements are

// used in Item elements and Client elements, and so

// both types would be returned.

XmlNodeList nodes = doc.SelectNodes("/Order/Items/Item/Name");

foreach (XmlNode node in nodes)

{

Console.WriteLine(node.InnerText);

}

Console.ReadLine();

}

}

}

The output of this program is as follows:

Electronic Protractor

Invisible Ink



Notes

XPath provides a rich and powerful search syntax, and it is impossible to explain all the variations you

can use in a short recipe. However, Table 6-1 outlines some of the key ingredients in more advanced

XPath expressions and includes examples that show how they would work with the order document. For

a more detailed reference, refer to the W3C XPath recommendation, at www.w3.org/TR/xpath.

Table 6-1. XPath Expression Syntax



Expression



Description



Example



/



Starts an absolute path

that selects from the root

node.



/Order/Items/Item selects all Item elements that are children

of an Items element, which is itself a child of the root Order

element.



//



Starts a relative path that

selects nodes anywhere.



//Item/Name selects all the Name elements that are children of

an Item element, regardless of where they appear in the

document.



276



www.it-ebooks.info



CHAPTER 6 ■ XML PROCESSING



Expression



Description



Example



@



Selects an attribute of a

node.



/Order/@id selects the attribute named id from the root

Order element.



*



Selects any element in the

path.



/Order/* selects both Items and Client nodes because both

are contained by a root Order element.



|



Combines multiple paths.



/Order/Items/Item/Name|Order/Client/Name selects the Name

nodes used to describe a Client and the Name nodes used to

describe an Item.



.



Indicates the current

(default) node.



If the current node is an Order, the expression ./Items refers

to the related items for that order.



..



Indicates the parent node.



//Name/.. selects any element that is parent to a Name, which

includes the Client and Item elements.



[ ]



Defines selection criteria

that can test a contained

node or an attribute value.



/Order[@id="2004-01-30.195496"] selects the Order

elements with the indicated attribute value.

/Order/Items/Item[Price > 50] selects products higher

than $50 in price.

/Order/Items/Item[Price > 50 and Name="Laser Printer"]

selects products that match two criteria.



startswith



Retrieves elements based

on what text a contained

element starts with.



/Order/Items/Item[starts-with(Name, "C")] finds all Item

elements that have a Name element that starts with the letter

C.



position



Retrieves elements based

on position.



/Order/Items/Item[position ()=2] selects the second Item

element.



count



Counts elements. You

specify the name of the

child element to count or

an asterisk (*) for all

children.



/Order/Items/Item[count(Price) = 1] retrieves Item

elements that have exactly one nested Price element.



■ Note XPath expressions and all element and attribute names you use inside them are always case-sensitive,

because XML itself is case-sensitive.



277



www.it-ebooks.info



CHAPTER 6 ■ XML PROCESSING



6-7. Read and Write XML Without Loading an Entire

Document into Memory

Problem

You need to read XML from a stream or write it to a stream. However, you want to process the

information one node at a time, rather than loading it all into memory with an XmlDocument.



Solution

To write XML, create an XmlWriter that wraps a stream and use Write methods (such as

WriteStartElement and WriteEndElement). To read XML, create an XmlReader that wraps a stream, and

call Read to move from node to node.



How It Works

The XmlWriter and XmlReader classes read or write XML directly from a stream one node at a time. These

classes do not provide the same features for navigating and manipulating your XML as XmlDocument, but

they do provide higher performance and a smaller memory footprint, particularly if you need to deal

with large XML documents.

Both XmlWriter and XmlReader are abstract classes, which means you cannot create an instance of

them directly. Instead, you should call the Create method of XmlWriter or XmlReader and supply a file or

stream. The Create method will return the right derived class based on the options you specify. This

allows for a more flexible model. Because your code uses the base classes, it can work seamlessly with

any derived class. For example, you could switch to a validating reader (as shown in the next recipe)

without needing to modify your code.

To write XML to any stream, you can use the streamlined XmlWriter. It provides Write methods that

write one node at a time. These include the following:





WriteStartDocument, which writes the document prologue, and WriteEndDocument,

which closes any open elements at the end of the document.







WriteStartElement, which writes an opening tag for the element you specify. You

can then add more elements nested inside this element, or you can call

WriteEndElement to write the closing tag.







WriteElementString, which writes an entire element, with an opening tag, a

closing tag, and text content.







WriteAttributeString, which writes an entire attribute for the nearest open

element, with a name and value.



Using these methods usually requires less code than creating an XmlDocument by hand, as

demonstrated in recipes 6-2 and 6-3.

To read the XML, you use the Read method of the XmlReader. This method advances the reader to the

next node and returns true. If no more nodes can be found, it returns false. You can retrieve



278



www.it-ebooks.info



CHAPTER 6 ■ XML PROCESSING



information about the current node through XmlReader properties, including its Name, Value, and

NodeType.

To find out whether an element has attributes, you must explicitly test the HasAttributes property

and then use the GetAttribute method to retrieve the attributes by name or index number. The

XmlTextReader class can access only one node at a time, and it cannot move backward or jump to an

arbitrary node, which gives much less flexibility than the XmlDocument class.



The Code

The following console application writes and reads a simple XML document using the XmlWriter and

XmlReader classes. This is the same XML document created in recipes 6-2 and 6-3 using the XmlDocument

class.

using

using

using

using



System;

System.Xml;

System.IO;

System.Text;



namespace Apress.VisualCSharpRecipes.Chapter06

{

public class Recipe06_07

{

private static void Main()

{

// Create the file and writer.

FileStream fs = new FileStream("products.xml", FileMode.Create);

// If you want to configure additional details (like indenting,

// encoding, and new line handling), use the overload of the Create

// method that accepts an XmlWriterSettings object instead.

XmlWriter w = XmlWriter.Create(fs);

// Start the document.

w.WriteStartDocument();

w.WriteStartElement("products");

// Write a product.

w.WriteStartElement("product");

w.WriteAttributeString("id", "1001");

w.WriteElementString("productName", "Gourmet Coffee");

w.WriteElementString("productPrice", "0.99");

w.WriteEndElement();

// Write another product.

w.WriteStartElement("product");

w.WriteAttributeString("id", "1002");

w.WriteElementString("productName", "Blue China Tea Pot");

w.WriteElementString("productPrice", "102.99");

w.WriteEndElement();



279



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

6-6. Find Elements with an XPath Search

Tải bản đầy đủ ngay(0 tr)

×