Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 60 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
60
Dung lượng
1,28 MB
Nội dung
<tr> <td style=”width: 101px; height: 41px”> First Name: </td> <td style=”width: 204px; height: 41px”> <asp:TextBox ID=”txtFirstName” runat=”server” Width=”201px”> </asp:TextBox> </td> </tr> <tr> <td style=”width: 101px; height: 41px”> Last Name: </td> <td style=”width: 204px; height: 41px”> <asp:TextBox ID=”txtLastName” runat=”server” Width=”201px”> </asp:TextBox> </td> </tr> <tr> <td style=”width: 101px; height: 41px”> Price: </td> <td style=”width: 204px; height: 41px”> <asp:TextBox ID=”txtPrice” runat=”server” Width=”201px”> </asp:TextBox> </td> </tr> <tr> <td colspan=”2” style=”width: 101px; height: 41px”> <asp:Button Text=”Save” runat=”server” ID=”btnSave” Width=”95px” OnClick=”btnSave_Click”/> </td> </tr> <tr> <td colspan=”2” style=”width: 101px; height: 41px”> <asp:Label runat=”server” ID=”lblResult” Width=”295px”/> </td> </tr> </table> </div> </form> </body> </html> Basically, Listing 6-5 provides a Web form where you can enter the details of a book. It captures the entered book details and saves them onto an XML file named NewBooks.xml. At the time of writing the file, it checks to see if the NewBooks.xml file is already available—if so, it appends the book details to the existing XML document; otherwise, it creates an XML document from scratch and adds the book details to that newly created document. Finally it saves the XML file using the Save() method. 154 Chapter 6 09_596772 ch06.qxd 12/13/05 11:13 PM Page 154 It all starts with a check to see if the XML file is already available in the file system. if (System.IO.File.Exists(xmlPath)) If the file is available, the file is loaded onto an XML document. doc.Load(xmlPath); As the name suggests, the CreateBookNode() method is a helper method that basically creates a book node that contains all the child nodes and the related attributes based on the details keyed in by the user. XmlNode bookNode = CreateBookNode(doc); After the book node is created, the next step is to append the book node to the root bookstore node. Before doing that, you need to get reference to the bookstore node. XmlNode bookStoreNode = doc.SelectSingleNode(“bookstore”); bookStoreNode.AppendChild(bookNode); If the NewBooks.xml file is not present in the directory, you need to create that XML file from scratch. Start by creating the XML declaration and append that to the XmlDocument object. XmlNode declarationNode = doc.CreateXmlDeclaration(“1.0”, “”, “”); doc.AppendChild(declarationNode); Add a comment indicating the purpose of the XML document by calling the CreateComment() method. XmlNode comment = doc.CreateComment(“This file represents a “ + “fragment of a book store inventory database”); doc.AppendChild(comment); After that, create the root bookstore node. XmlNode bookstoreNode = doc.CreateElement(“bookstore”); Again create the book node using the CreateBookNode() helper method and then append the returned book node to the root bookstore node. XmlNode bookNode = CreateBookNode(doc); //Append the book node to the bookstore node bookstoreNode.AppendChild(bookNode); //Append the bookstore node to the document doc.AppendChild(bookstoreNode); Finally, save the XML file. doc.Save(xmlPath); If you navigate to the above page using the browser, you see the output shown in Figure 6-5. 155 XML DOM Object Model 09_596772 ch06.qxd 12/13/05 11:13 PM Page 155 Figure 6-5 Figure 6-5 shows the output produced by the page after you enter the book details and save them. After saving the book details, navigate to the NewBooks.xml file through the browser, and you see the result as shown in Figure 6-6. Figure 6-6 156 Chapter 6 09_596772 ch06.qxd 12/13/05 11:13 PM Page 156 Changing Node Data Node data can be changed after it has been created. For example, suppose that you want to change the price of a specific book after it has been released. To reflect this in the document, you would need to find the <title> node that contains the specific book and update its sibling <price> node with the new value. The following line of code shows how to do this using the Value property of the XmlNode class: priceNode.FirstChild.Value = “10.99”; Deleting Nodes To delete a node, simply remove it from the document. The RemoveChild() method of the XmlNode class accomplishes this. When called on an XmlNode object, the passed child node will be removed from its list of child nodes. For example, to delete the <title> node from the XML document, use the follow- ing code: XmlDocument doc = new XmlDocument(); doc.LoadXml(“<book genre=’ autobiography’’>” + “<title>The Autobiography of Benjamin Franklin</title>” + “</book>”); XmlNode root = doc.DocumentElement; //Remove the title element. root.RemoveChild(root.FirstChild); In the example, the XmlDocument object is loaded from an XML string. After an XML document is loaded in memory, you get reference to the specific nodes that you want to remove from the XML document. After the reference to the specific node is obtained, invoke the RemoveChild() method, passing in the node to be removed. Handling Events Raised by the XmlDocument Before looking at the steps involved in handling the events raised by the XmlDocument, Table 6-3 briefly reviews the events raised by the XmlDocument class. Table 6-3. Events of the XmlDocument Class Event Description NodeChanged Raised when the Value property of a node belonging to this document has been changed NodeChanging Raised when the Value property of a node belonging to this document is about to be changed NodeInserted Raised when a node belonging to this document has been inserted into another node NodeInserting Raised when a node belonging to this document is about to be inserted into another node NodeRemoved Raised when a node belonging to this document has been removed from its parent NodeRemoving Raised when a node belonging to this document is about to be removed from this document 157 XML DOM Object Model 09_596772 ch06.qxd 12/13/05 11:13 PM Page 157 All these events require the same delegate for the event handler, as follows: public delegate void XmlNodeChangedEventHandler( object sender, XmlNodeChangedEventArgs e); The XmlNodeChangedEventArgs structure contains the event data. The structure has six interesting properties: ❑ Node —Returns an XmlNode object that denotes the node that is being added, removed, or changed. ❑ OldParent —Returns an XmlNode object representing the parent of the node before the opera- tion began. ❑ NewParent —Returns an XmlNode object representing the new parent of the node after the operation is complete. The property is set to null if the node is being removed. If the node is an attribute, the property returns the node to which the attribute refers. ❑ OldValue —Returns the original value of the node before the operation began ❑ NewValue —Returns the new value of the node ❑ Action —Contains a value indicating what type of change is occurring on the node by return- ing an enumeration of type XmlNodeChangedAction. Allowable values, listed in the XmlNodeChangedAction enumeration type are Insert, Remove, and Change. Some of the actions you can take on an XML DOM are compound actions consisting of several steps, each of which could raise its own event. For example, be prepared to handle several events when you set the InnerXml property. In this case, multiple nodes could be created and appended, resulting in as many NodeInserting/NodeInserted pairs being raised. In some cases, the AppendChild() method of the XmlNode might fire a pair of NodeRemoving/NodeRemoved events prior to actually proceeding with the insertion. By design, to ensure XML well-formedness, AppendChild() checks whether the node you are adding already exists in the document. If it does, the existing node is first removed to avoid identical nodes in the same subtree. The following code shows how to set up a handler for the NodeInserted event. //Add a new event handler. XmlDocument doc = new XmlDocument(); doc.NodeInserted += new XmlNodeChangedEventHandler( NodeInsertedHandler); //Define the event handler. void NodeInsertedHandler(Object src, XmlNodeChangedEventArgs args) { Response.Write(“Node “ + args.Node.Name + “ inserted”); } Inside the NodeInsertedHandler() method, the name of the node is retrieved from the XmlNodeChangedEventArgs object and displayed in the browser. As you can see, events provide with you with a flexible approach that can be used to synchronize changes between documents. 158 Chapter 6 09_596772 ch06.qxd 12/13/05 11:13 PM Page 158 The XmlDocumentFragment Class As you have seen in previous sections, after an XML document is loaded in memory, you can enter all the needed changes by simply accessing the property of interest and modifying the underlying value. For example, to change the value of an attribute, you proceed as follows: // Retrieve a particular node and update an attribute XmlNode node = doc.SelectSingleNode(“book”); node.Attributes[“genre”] = “novel”; To insert many nodes at the same time and in the same parent, you can take advantage of a little trick based on the concept of a document fragment. To this end, .NET Framework provides a class named XmlDocumentFragment that provides a lightweight object that is useful for tree operations. In essence, you concatenate all the necessary markup into a string and then create a document fragment, as shown here: XmlDocumentFragment docFragment = doc.CreateDocumentFragment(); docFragment.InnerXml = “<book genre=’novel’> </book>”; parentNode.AppendChild(docFragment); After creating an XmlDocumentFragment object, set its InnerXml property to the string value and add the XmlDocumentFragment to the parent node. The nodes defined in the body of the fragment are inserted one after the next. Listing 6-6 shows how the CreateBookNode() method in Listing 6-5 can be modified to take advantage of the XmlDocumentFragment object. Listing 6-6: Creating Fragments of XML Using XmlDocumentFragment XmlNode CreateBookNode(XmlDocument doc) { XmlDocumentFragment docFragment = doc.CreateDocumentFragment(); docFragment.InnerXml = “<book genre=’” + txtGenre.Text + “‘>” + “<title>” + txtTitle.Text +” </title>” + “<author><first-name>” + txtFirstName.Text + “</first-name>” + “<last-name>” + txtLastName.Text + “</last-name></author>” + “<price>” + txtPrice.Text + “</price></book>”; return docFragment; } In general, when you set the InnerXml property on an XmlNode-based class, any detected markup text will be parsed, and the new contents will replace the existing contents. For this reason, if you want to simply add new children to a node, pass through the XmlDocumentFragment class, as described in the previous paragraph, and avoid using InnerXml directly on the target node. XPath Support in XML DOM The XPath language enables you to locate nodes in your XML data that match the specified criteria. An XPath expression can specify criteria by evaluating either the position of a node in the document hierarchy, data values of the node, or a combination of both. Basic XPath syntax uses a path such as notation. For example, the path /bookstore/book/author indicates an author element that is nested inside a book element, which, in turn, is nested in a root bookstore element. You can also use XPath to locate specific nodes. For example, this expression locates all book nodes: //bookstore/book 159 XML DOM Object Model 09_596772 ch06.qxd 12/13/05 11:13 PM Page 159 But this expression matches only a node with the specific genre attribute value of novel: //bookstore/book/[@genre=’novel’]/author 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. XPath provides rich and powerful search syntax, and it’s impossible to explain all of the variations you can use in a brief discussion. However, Table 6-4 outlines some of the key ingredients in more advanced XPath expressions and includes examples that show how they would work with the books.xml document. Table 6-4. XPath Expression Syntax Expression Meaning / Starts an absolute path that selects from the root node. /bookstore/book/title selects all title elements that are children of the book element, which is itself a child of the root bookstore element. // Starts a relative path that selects nodes anywhere. //book/title selects all of the title elements that are children of a book element, regardless of where they appear in the document. @ Selects an attribute of a node. /book/@genre selects the attribute named genre from the root book element. * Selects any element in the path. /book/* selects both title and author nodes because both are contained by a root book element. | Union operator that returns the union of the results of two paths. /bookstore/book/title | bookstore/book/author selects the title nodes used to describe a title and the author nodes used to describe an author. . Indicates the current default node. Indicates the parent node. //author/ selects any element that is parent to an author, which includes the book elements. [] Define selection criteria that can test a contained node or attribute value. /book[@genre=”autobiography”] selects the book elements with the indicated attribute value. starts-with This function retrieves elements based on what text a contained element starts with. /bookstore/book/author[starts-with(first-name, “B”)] finds all author elements that have a first-name element that starts with the letter B. 160 Chapter 6 09_596772 ch06.qxd 12/13/05 11:13 PM Page 160 Expression Meaning position This function retrieves elements based on position. /bookstore/book[position()=2] selects the second book element. count This function counts elements. You specify the name of the child element to count, or an asterisk ( *) for all children. /bookstore/book/author[count(first-name) = 1] retrieves author elements that have exactly one nested first-name element. Listing 6-7 shows an example that allows you to select an XPath expression from a drop-down list, apply that XPath to an XML document, and display the contents of the resultant object. Listing 6-7: Evaluating XPath Expressions <%@ Page Language=”C#” %> <%@ Import Namespace=”System.Xml” %> <script runat=”server”> void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { ddlExpressions.Items.Add(“//book/title”); ddlExpressions.Items.Add(“//book[@genre=’novel’]/title”); ddlExpressions.Items.Add(“//book/author/first-name”); ddlExpressions.Items.Add(“//book[@genre=’philosophy’]/title”); ddlExpressions.Items.Add(“//book/price”); ddlExpressions.Items.Add(“//book[3]/title”); ddlExpressions.SelectedIndex = 0; //Set the default selection UpdateDisplay(); } } void ddlExpressions_SelectedIndexChanged(object sender, EventArgs e) { //Display the value produced by evaluating the XPath Expression UpdateDisplay(); } void UpdateDisplay() { lstOutput.Items.Clear(); string xmlPath = Request.PhysicalApplicationPath + @”\App_Data\Books.xml”; XmlDocument doc = new XmlDocument(); doc.Load(xmlPath); XmlNodeList nodeList = doc.DocumentElement.SelectNodes(ddlExpressions.SelectedItem.Text); foreach (XmlNode child in nodeList) { lstOutput.Items.Add(“Node Name:” + child.Name); lstOutput.Items.Add(“Node Value:” + child.FirstChild.Value); } 161 XML DOM Object Model 09_596772 ch06.qxd 12/13/05 11:13 PM Page 161 } </script> <html xmlns=”http://www.w3.org/1999/xhtml” > <head runat=”server”> <title>XPath Example</title> </head> <body> <form id=”form1” runat=”server”> <div> Select the XPath Expression: <asp:DropDownList ID=”ddlExpressions” AutoPostBack=”true” runat=”server” Width=”410px” OnSelectedIndexChanged=”ddlExpressions_SelectedIndexChanged”> </asp:DropDownList> <br/><br/> <asp:ListBox ID=”lstOutput” runat=”server” Width=”587px” Height=”168px”> </asp:ListBox> </div> </form> </body> </html> The Page_Load event loads the drop-down list box with the set of predefined XPath expressions. if (!Page.IsPostBack) { ddlExpressions.Items.Add(“//book/title”); ddlExpressions.Items.Add(“//book[@genre=’novel’]/title”); ddlExpressions.Items.Add(“//book/author/first-name”); ddlExpressions.Items.Add(“//book[@genre=’philosophy’]/title”); ddlExpressions.Items.Add(“//book/price”); ddlExpressions.Items.Add(“//book[3]/title”); ddlExpressions.SelectedIndex = 0; //Set the default selection UpdateDisplay(); } After loading all the values, a helper method named UpdateDisplay() is invoked. This method basically updates the display on a results list box based on the selected XPath expression. This method is also invoked from the SelectedIndexChanged event of the drop-down box to evaluate the selected XPath expression and display the results through the list box. Code inside the UpdateDisplay() method is simple and straightforward. After loading the XmlDocument object with the contents of an XML file, it simply invokes the SelectNodes() method of the XmlElement object that is returned by invoking the DocumentElement property of the XmlDocument object. To the SelectNodes() method, the selected value in the drop-down list is supplied as an argument. The return value of the SelectNodes() method is an XmlNodeList object, which is then iterated through a for each loop. Inside the for each loop, the name and value of the node are added to the results list box. XmlNodeList nodeList = doc.DocumentElement.SelectNodes(ddlExpressions.SelectedItem.Text); foreach (XmlNode child in nodeList) { 162 Chapter 6 09_596772 ch06.qxd 12/13/05 11:13 PM Page 162 lstOutput.Items.Add(“Node Name:” + child.Name); lstOutput.Items.Add(“Node Value:” + child.FirstChild.Value); } The output produced by the page looks similar to Figure 6-7. Figure 6-7 In Figure 6-7, selecting an XPath expression in the drop-down list results in that XPath expression being evaluated, and the output of that is displayed in the list box. Performance Optimization with XPathNavigator Another way to use XPath to query your XML data is to create and use an XPathNavigator object. The XPathNavigator class, in conjunction with the other classes in the System.Xml.XPath namespace such as XPathDocument, XPathExpression, and the XPathNodeIterator, enables you to optimize performance when working with XPath queries. The XPathNavigator class has methods such as Select, Compile, and Evaluate to perform queries on your XML data by using XPath expressions. Among all the other things that you can do with an XPathNavigator object, keep in mind, is the use of XPathNavigator object to process the contents of an XML document in an efficient way. For example, if you are going to perform the same query a number of times, perhaps on a collection of documents, the query will execute significantly faster if you pre-compile the expression. You do this by calling the Compile() method on the navigator, passing in an XPath expression as a string, and getting back an instance of an XPathExpression object. You can pass that XPathExpression object to the Select method, and the execution of the Select method will be much quicker than if you passed in the XPath as a string every time. By providing a cursor model, the XPathNavigator class enables you to navigate and edit XML information items as instances of the XQuery 1.0 and XPath 2.0 Data Model. An XPathNavigator object is created from a class that implements the IXPathNavigable interface such as the XPathDocument and XmlDocument classes. Table 6-5 lists the key methods of the XPathNavigator class. 163 XML DOM Object Model 09_596772 ch06.qxd 12/13/05 11:13 PM Page 163 [...]... Framework 2.0 string xmlPath = Request.PhysicalApplicationPath + @”\App_Data\Books .xml ; string xsdPath = Request.PhysicalApplicationPath + @”\App_Data\Books.xsd”; XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.Schemas.Add(null, XmlReader.Create(xsdPath)); XmlReader reader = XmlReader.Create(xmlPath, settings); XmlDocument doc = new XmlDocument();... contained in the price node 168 XML DOM Object Model Listing 6-9: Using XPathNavigator to Update an XML Document void Page_Load(object sender, EventArgs e) { //Set the ContentType to XML to write XML values Response.ContentType = “text /xml ; string xmlPath = Request.PhysicalApplicationPath... Transform (IXPathNavigable, XmlWriter) (string, string) (string, XmlWriter) (XmlReader, XmlWriter) (IXPathNavigable, XsltArgumentList, Stream) (IXPathNavigable, XsltArgumentList, TextWriter) (IXPathNavigable, XsltArgumentList, XmlWriter) (string, XsltArgumentList, Stream) (string, XsltArgumentList, TextWriter) (string, XsltArgumentList, XmlWriter) (XmlReader, XsltArgumentList, Stream) (XmlReader, XsltArgumentList,... schema and contents of XML documents The overall programming interface of the XmlDocument class might look familiar to those of you who have spent some time working with the COM-based MSXML library The XmlDocument class provides methods to load XML documents from a variety of sources, including XML readers and streams To locate a node in the in-memory tree that represents the original XML document, you... a Style Sheet Statically To statically link a style sheet to an XML document, you add the < ?xml- stylesheet?> processing directive to the start of the source XML For instance, if the books.xsl and the books .xml files are in the same directory, you could add the following to the top of books .xml < ?xml version=”1.0” encoding=”UTF-8” ?> < ?xml- stylesheet type=”text/xsl” href=”books.xsl” ?> XML DOM Object Model Validating XML in an XmlDocument Chapter 5 provided a complete discussion of the validation features available for the XML reader classes With the release of NET Framework 2.0, Microsoft has built in the validation feature right into the XmlDocument itself By using this feature, you can perform XML schema validation of the entire subtree... XsltArgumentList, XmlWriter) (XmlReader, XsltArgumentList, Stream) (XmlReader, XsltArgumentList, TextWriter) (XmlReader, XsltArgumentList, XmlWriter) (XmlReader, XsltArgumentList, XmlWriter, XmlResolver) The XML input to the Transform() method can be specified as an IXPathNavigable object, a string, or an XmlReader object The parameters and extension objects are passed to the XSL style sheet using the XsltArgumentList... transformations effectively in ASP.NET Chapter 7 A Primer on XSLT XSLT is a language that enables you to convert XML documents into other XML documents, into HTML documents, or into almost anything you like When you specify a series of XSLT instructions for converting a class of XML documents, you do it by creating an “XSL style sheet.” An XSL style sheet is an XML document that uses specialized XML elements and... method of the XmlDocument object Summar y This chapter introduced the basic concepts of XML DOM in NET Framework and provided a concise overview of the NET DOM classes available to read, store, and manipulate XML documents The classes in the System .Xml namespaces contain probably the richest collection of XML- related functionalities available thus far in any other software development platform XML DOM exposes... Transforming XML Data with XSLT Note that the books .xml file shown in Listing 7-1 is used throughout all the examples presented in this chapter Now that you have created the XML file, it is time to create the style sheet that transforms the XML into HTML Listing 7-2 shows the declaration of the style sheet Listing 7-2: XSLT Style Sheet Used for Transforming the XML < ?xml version=”1.0”?> . XmlDocument object as you are building the XML DOM tree. 171 XML DOM Object Model 09 _5967 72 ch06.qxd 12/ 13 /05 11:13 PM Page 171 09 _5967 72 ch06.qxd 12/ 13 /05 11:13 PM Page 1 72 Transforming XML. style=”width: 101 px; height: 41 px”> Last Name: </td> <td style=”width: 20 4px; height: 41 px”> < ;asp: TextBox ID=”txtLastName” runat=”server” Width= 20 1px”> < /asp: TextBox> </td> </tr> <tr> <td. Width= 20 1px”> < /asp: TextBox> </td> </tr> <tr> <td style=”width: 101 px; height: 41 px”> Price: </td> <td style=”width: 20 4px; height: 41 px”> < ;asp: TextBox ID=”txtPrice” runat=”server” Width= 20 1px”> < /asp: TextBox> </td> </tr> <tr> <td