Provides support for rapid application development (RAD) designers to parse data-binding expressions that use XPath expressions. This class cannot be inherited.
Namespace: System.Web.UI
Assembly: System.Web (in System.Web.dll)
You can use the overloaded Eval method of this class to bind to the result of an XPath expression executed against an object that implements the IXPathNavigable interface, such as an XmlNode. You can use the Select method to retrieve the results of an XPath expression executed against an IXPathNavigable object as an IEnumerable list of nodes. This list of nodes can be enumerated directly or assigned to the DataSource property of a list control, such as a Repeater or DataList.
You can use a simplified version of data-binding syntax when using the XPathBinder methods declaratively. Instead of calling XPathBinder.Eval(Container.DataItem, xpath) you can use XPath(xpath). Similarly, instead of calling XPathBinder.Select(Container.DataItem, xpath), you can use XPathSelect(xpath) to retrieve an IEnumerable set of nodes. When using this simplified syntax, the Eval and Select methods assume a default Container.DataItem context object.
For more information about data binding to ASP.NET server controls, see Data-Binding Expression Syntax.
The following code example demonstrates how to use an XmlDataSource control with a templated Repeater control to display XML data. This example has two parts:
- A Web Forms page that displays XML data.
- An XML file that contains the data.
Visual Basic
%@ Page Language="VB" %>
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
html >
head runat="server">
title>Order/title>
/head>
body>
form id="form1" runat="server">
asp:XmlDataSource
runat="server"
id="XmlDataSource1"
XPath="orders/order"
DataFile="order.xml" />
asp:Repeater ID="Repeater1"
runat="server"
DataSourceID="XmlDataSource1">
ItemTemplate>
h2>Order/h2>
table>
tr>
td>Customer/td>
td>%#XPath("customer/@id")%>/td>
td>%#XPath("customername/firstn")%>/td>
td>%#XPath("customername/lastn")%>/td>
/tr>
tr>
td>Ship To/td>
td>%#XPath("shipaddress/address1")%>/font>/td>
td>%#XPath("shipaddress/city")%>/td>
td>%#XPath("shipaddress/state")%>,
%#XPath("shipaddress/zip")%>/td>
/tr>
/table>
h3>Order Summary/h3>
asp:Repeater ID="Repeater2"
DataSource='%#XPathSelect("summary/item")%>'
runat="server">
ItemTemplate>
b>%#XPath("@dept")%>/b> -
%#XPath(".")%>br />
/ItemTemplate>
/asp:Repeater>
hr />
/ItemTemplate>
/asp:Repeater>
/form>
/body>
/html>
?xml version="1.0" encoding="iso-8859-1"?>
orders>
order>
customer id="12345" />
customername>
firstn>John/firstn>
lastn>Doe/lastn>
/customername>
transaction id="12345" />
shipaddress>
address1>1234 Tenth Avenue/address1>
city>Bellevue/city>
state>Washington/state>
zip>98001/zip>
/shipaddress>
summary>
item dept="tools">screwdriver/item>
item dept="tools">hammer/item>
item dept="plumbing">fixture/item>
/summary>
/order>
/orders>
I'm using the XmlDataSource control (GridView consumes the data) and one of my fields in the xml is date time. I want to format it to show only the date like this:
So my question is why there is overload with 2 parameters (2 strings, the second is the format) when it is actually unusable?
%# XPath("date", "{0:d}") %>Unfortunatelly this did not work. Digging into the XPathBinder class it is obvious that what is past is just strings. So I have end up with parsing the string to date time and then formating it.
So my question is why there is overload with 2 parameters (2 strings, the second is the format) when it is actually unusable?
The problem is actually with the XmlDataSource and the fact that it doesn't support schema loading, so the values are always strings. If you have a data source that supports typed-XML (for example, with schema support), then the formatting on XPath() would work. For now a workaround would be something like this:
%# String.Format("{0:d}", XPath("date")) %>
Increasingly, the data you have to work with in your Web applications is presented as XML. It might be static XML documents, or (more likely) XML that has been dynamically generated by another application or a Web Service. ASP.NET 2.0 contains several new data source controls, and three of these are specifically designed to work with XML data:
* The XmlDataSource control is designed to work with hierarchical data presented as XML, in other words data where there can be multiple and irregular nesting of elements.
* The DataSetDataSource control is designed to work with XML that represents a flat table, rather than being hierarchical in nature. In other words, XML data that effectively represents a DataTable within a DataSet.
* The SiteMapDataSource control is a logical extension of the XmlDataSource control and is specifically designed to expose an XML-formatted map of a Web site or application. It is generally used along with several other new controls in ASP.NET 2.0 that generate menus and other site navigation aids.
This article does not explore the new data source controls, but instead focuses on the way that data binding is used to access and present individual items of data that these controls expose.
The XPathBinder Object
The issue at hand is: how do you specify an element or a series of elements when creating output where the data is XML rather than the more usual "rows and columns" format? The existing Eval and Bind methods rely on the column names and are used when the source data is a rowset - such as that exposed by the SqlDataSource control.
The answer is that there is a new binding object in ASP.NET 2.0, called the XPathBinder. This works much like the DataBinder object that is now the default context when data binding to rowset data. The XPathBinder object exposes two methods that can be used to select items from an XML document, the Eval method and the Select method.
The Eval method, which has exactly the same syntax as the DataBinder.Eval method, returns the value of a single element or attribute from the current context. The current context is effectively the set of elements exposed by the parent of this element, rather like the set of columns in the current row of a relational data rowset. You can optionally format the returned value using the same approach as described for the DataBinder.Eval method:
%# XPathBinder.Eval(Container.DataItem, "xpath"[, "format"]) %>
However, in line with the simplified syntax for rowset data binding, the equivalent has been provided for XML data sources as well. Rather than specifying the XPathBinder.Eval method, you simply use a method of the TemplateControl named XPath:
%# XPath("xpath"[, "format"]) %>
The second method of the XPathBinder is the Select method. This method is designed to return a collection of node values, rather than a single value (like the Eval/XPath method does). For this reason, there is no format parameter for the Select method. The full syntax of this method is:
%# XPathBinder.Select(Container.DataItem, "xpath") %>
Again, there is a simplified form:
%# XPathSelect("xpath") %>
The xpath parameter to the XPath and XPathSelect methods is an XPath expression that identifies the nodes that you want to bind to the controls in your page. XPath expressions are extremely powerful, and can be used to return single nodes (elements or attributes) from anywhere in an XML document, or collections of nodes. For more details of XPath and the techniques for writing XPath expressions, start at the W3C site at http://www.w3.org/TR/xpath.
Using the XPath Method To demonstrate the XPath method, we need some XML to act as the source data. For simplicity, this example uses a disk file named employees.xml, which looks like this:
?xml version="1.0" ?>
employee-list>
employee id="2456">
name>Mike/name>
department>Sales/department>
phone>3867/phone>
/employee>
employee id="1965">
name>Nikita/name>
department>Marketing/department>
phone>1442/phone>
/employee>
... more employees here ...
/employee-list>
To expose this for data binding, we use an XmlDataSource control, specifying the disk file as the XML source data:
asp:XmlDataSource id="ds1" runat="server" DataFile="employees.xml"
/>
Now the data can be bound to any control using the new XML data binding statements. This example uses a FormView control, with the DataSourceID attribute set to the ID of the XmlDataSource control so as to link the two controls together. Then, inside the ItemTemplate section, individual controls that generate the output for the FormView control are declared, just as in the earlier examples that used a SqlDataSource control. This time, however, the XPath data binding method is used, because the items in the source data are XML nodes:
asp:FormView ID="formview1" runat="server" DataSourceID="ds1" AllowPaging="True">
ItemTemplate>
ID:b>
asp:Label ID="lblID" Runat="server"
Text='%# XPath("@id") %>' />/b>br
/>
Name:b>
asp:Label ID="lblName" Runat="server"
Text='%# XPath("name") %>' />/b>br
/>
Dept:b>
asp:Label ID="lblDept" Runat="server"
Text='%# XPath("department") %>'
/>/b>br />
Phone:b>
asp:Label ID="lblPhone" Runat="server"
Text='%# XPath("phone") %>' />/b>
/ItemTemplate>
/asp:FormView>
Each Label control in the ItemTemplate of the FormView control is bound to one of the nodes in the source data. The nature of the XML file means that the employee> element is the one that is repeated within the FormView control (in other words, it is the equivalent of the "rows" in relational data terms). So the Label controls that display the name, department and phone number can be bound directly to the child elements within each employee> element by using the element name in the XPath method. The ID of each employee is stored in an attribute of that employee> element, and so in this case the attribute name is used in the XPath method, as XPath("@attribute-name").
The screenshot below shows the results. This example, xpath-xmldatasource.aspx, is included in the samples you can download for this article from http://www.daveandal.net/articles/databinding-syntax/.
Figure 4
Using the XPathSelect Method
The XPath method shown in the previous example returns a single value based on the XPath provided as a parameter. The XPathSelect method uses an XPath expression to return a collection of nodes from an XML document. To demonstrate the XPathSelect method, you use a more complex XML file as the data source. You can see that it contains a second level of nested elements in the form of multiple phone numbers for each employee:
?xml version="1.0" ?>
employee-list>
employee id="1437">
name>Mike/name>
department>Sales/department>
phone-list>
phone>3867/phone>
phone>773-6482/phone>
phone>(278) 555-3678/phone>
phone>(643) 555-1101/phone>
/phone-list>
/employee>
employee id="7290">
name>Nikita/name>
department>Marketing/department>
phone-list>
phone>1442/phone>
phone>(278) 555-8521/phone>
phone>(532) 555-4444/phone>
/phone-list>
/employee>
... more employees here ...
/employee-list>
An XmlDataSource control is used to expose this data for data binding, in exactly the same way as the previous example. However, the XPathSelect method can now be used to get a collection of phone numbers for each employee. In the next listing, the first section of the ItemTemplate is the same as in the previous example.
asp:FormView ID="formview1" runat="server" DataSourceID="ds1" AllowPaging="True">
ItemTemplate>
ID:b>
asp:Label ID="lblID" Runat="server"
Text='%# XPath("@id") %>' />/b>br
/>
Name:b>
asp:Label ID="lblName" Runat="server"
Text='%# XPath("name") %>' />/b>br
/>
Dept:b>
asp:Label ID="lblDept" Runat="server"
Text='%# XPath("department") %>'
/>/b>br />
Phone Numbers:br />
asp:Repeater DataSource='%# XPathSelect("phone-list/phone")
%>' runat="server">
ItemTemplate>
* asp:Label ID="lblPhone" runat="server"
Text='%# XPath(".") %>' />br />
/ItemTemplate>
/asp:Repeater>
/ItemTemplate>
/asp:FormView>
The difference is in the addition of a Repeater control to display the list of phone numbers for each employee. The XPathSelect method is used to set the DataSource for the Repeater to a collection of the elements containing the phone numbers. The XPath "phone-list/phone" selects all the phone> elements that are children of the current phone-list> element (the one within the current employee> element). Then, inside the Repeater control, the value of each phone> element is displayed in a Label control. The XPath ".", which used to set the Text attribute of the Label control, simply returns the value of the current element.
The screenshot below shows the results. This example, xpathselect-xmldatasource.aspx, is included in the samples you can download for this article from http://www.daveandal.net/articles/databinding-syntax/.
* The XmlDataSource control is designed to work with hierarchical data presented as XML, in other words data where there can be multiple and irregular nesting of elements.
* The DataSetDataSource control is designed to work with XML that represents a flat table, rather than being hierarchical in nature. In other words, XML data that effectively represents a DataTable within a DataSet.
* The SiteMapDataSource control is a logical extension of the XmlDataSource control and is specifically designed to expose an XML-formatted map of a Web site or application. It is generally used along with several other new controls in ASP.NET 2.0 that generate menus and other site navigation aids.
This article does not explore the new data source controls, but instead focuses on the way that data binding is used to access and present individual items of data that these controls expose.
The XPathBinder Object
The issue at hand is: how do you specify an element or a series of elements when creating output where the data is XML rather than the more usual "rows and columns" format? The existing Eval and Bind methods rely on the column names and are used when the source data is a rowset - such as that exposed by the SqlDataSource control.
The answer is that there is a new binding object in ASP.NET 2.0, called the XPathBinder. This works much like the DataBinder object that is now the default context when data binding to rowset data. The XPathBinder object exposes two methods that can be used to select items from an XML document, the Eval method and the Select method.
The Eval method, which has exactly the same syntax as the DataBinder.Eval method, returns the value of a single element or attribute from the current context. The current context is effectively the set of elements exposed by the parent of this element, rather like the set of columns in the current row of a relational data rowset. You can optionally format the returned value using the same approach as described for the DataBinder.Eval method:
%# XPathBinder.Eval(Container.DataItem, "xpath"[, "format"]) %>
However, in line with the simplified syntax for rowset data binding, the equivalent has been provided for XML data sources as well. Rather than specifying the XPathBinder.Eval method, you simply use a method of the TemplateControl named XPath:
%# XPath("xpath"[, "format"]) %>
The second method of the XPathBinder is the Select method. This method is designed to return a collection of node values, rather than a single value (like the Eval/XPath method does). For this reason, there is no format parameter for the Select method. The full syntax of this method is:
%# XPathBinder.Select(Container.DataItem, "xpath") %>
Again, there is a simplified form:
%# XPathSelect("xpath") %>
The xpath parameter to the XPath and XPathSelect methods is an XPath expression that identifies the nodes that you want to bind to the controls in your page. XPath expressions are extremely powerful, and can be used to return single nodes (elements or attributes) from anywhere in an XML document, or collections of nodes. For more details of XPath and the techniques for writing XPath expressions, start at the W3C site at http://www.w3.org/TR/xpath.
Using the XPath Method To demonstrate the XPath method, we need some XML to act as the source data. For simplicity, this example uses a disk file named employees.xml, which looks like this:
?xml version="1.0" ?>
employee-list>
employee id="2456">
name>Mike/name>
department>Sales/department>
phone>3867/phone>
/employee>
employee id="1965">
name>Nikita/name>
department>Marketing/department>
phone>1442/phone>
/employee>
... more employees here ...
/employee-list>
To expose this for data binding, we use an XmlDataSource control, specifying the disk file as the XML source data:
asp:XmlDataSource id="ds1" runat="server" DataFile="employees.xml"
/>
Now the data can be bound to any control using the new XML data binding statements. This example uses a FormView control, with the DataSourceID attribute set to the ID of the XmlDataSource control so as to link the two controls together. Then, inside the ItemTemplate section, individual controls that generate the output for the FormView control are declared, just as in the earlier examples that used a SqlDataSource control. This time, however, the XPath data binding method is used, because the items in the source data are XML nodes:
asp:FormView ID="formview1" runat="server" DataSourceID="ds1" AllowPaging="True">
ItemTemplate>
ID:b>
asp:Label ID="lblID" Runat="server"
Text='%# XPath("@id") %>' />/b>br
/>
Name:b>
asp:Label ID="lblName" Runat="server"
Text='%# XPath("name") %>' />/b>br
/>
Dept:b>
asp:Label ID="lblDept" Runat="server"
Text='%# XPath("department") %>'
/>/b>br />
Phone:b>
asp:Label ID="lblPhone" Runat="server"
Text='%# XPath("phone") %>' />/b>
/ItemTemplate>
/asp:FormView>
Each Label control in the ItemTemplate of the FormView control is bound to one of the nodes in the source data. The nature of the XML file means that the employee> element is the one that is repeated within the FormView control (in other words, it is the equivalent of the "rows" in relational data terms). So the Label controls that display the name, department and phone number can be bound directly to the child elements within each employee> element by using the element name in the XPath method. The ID of each employee is stored in an attribute of that employee> element, and so in this case the attribute name is used in the XPath method, as XPath("@attribute-name").
The screenshot below shows the results. This example, xpath-xmldatasource.aspx, is included in the samples you can download for this article from http://www.daveandal.net/articles/databinding-syntax/.
Figure 4
Using the XPathSelect Method
The XPath method shown in the previous example returns a single value based on the XPath provided as a parameter. The XPathSelect method uses an XPath expression to return a collection of nodes from an XML document. To demonstrate the XPathSelect method, you use a more complex XML file as the data source. You can see that it contains a second level of nested elements in the form of multiple phone numbers for each employee:
?xml version="1.0" ?>
employee-list>
employee id="1437">
name>Mike/name>
department>Sales/department>
phone-list>
phone>3867/phone>
phone>773-6482/phone>
phone>(278) 555-3678/phone>
phone>(643) 555-1101/phone>
/phone-list>
/employee>
employee id="7290">
name>Nikita/name>
department>Marketing/department>
phone-list>
phone>1442/phone>
phone>(278) 555-8521/phone>
phone>(532) 555-4444/phone>
/phone-list>
/employee>
... more employees here ...
/employee-list>
An XmlDataSource control is used to expose this data for data binding, in exactly the same way as the previous example. However, the XPathSelect method can now be used to get a collection of phone numbers for each employee. In the next listing, the first section of the ItemTemplate is the same as in the previous example.
asp:FormView ID="formview1" runat="server" DataSourceID="ds1" AllowPaging="True">
ItemTemplate>
ID:b>
asp:Label ID="lblID" Runat="server"
Text='%# XPath("@id") %>' />/b>br
/>
Name:b>
asp:Label ID="lblName" Runat="server"
Text='%# XPath("name") %>' />/b>br
/>
Dept:b>
asp:Label ID="lblDept" Runat="server"
Text='%# XPath("department") %>'
/>/b>br />
Phone Numbers:br />
asp:Repeater DataSource='%# XPathSelect("phone-list/phone")
%>' runat="server">
ItemTemplate>
* asp:Label ID="lblPhone" runat="server"
Text='%# XPath(".") %>' />br />
/ItemTemplate>
/asp:Repeater>
/ItemTemplate>
/asp:FormView>
The difference is in the addition of a Repeater control to display the list of phone numbers for each employee. The XPathSelect method is used to set the DataSource for the Repeater to a collection of the elements containing the phone numbers. The XPath "phone-list/phone" selects all the phone> elements that are children of the current phone-list> element (the one within the current employee> element). Then, inside the Repeater control, the value of each phone> element is displayed in a Label control. The XPath ".", which used to set the Text attribute of the Label control, simply returns the value of the current element.
The screenshot below shows the results. This example, xpathselect-xmldatasource.aspx, is included in the samples you can download for this article from http://www.daveandal.net/articles/databinding-syntax/.