Inserting, Updating, Deleting, and Cloning Nodes

only for RuBoard

This section discusses how to use the most helpful features in the DOM API: creating content, inserting, updating, and deleting the nodes into the DOM document structure.

In this section, you create a new project, called CSMSXML, that you use for the next few examples in this chapter. Figure 5.5 shows the creation of this new project.

Figure 5.5. Creating the CSMSXML project.
graphics/05fig05.gif

Rename the default file that was created with the name webform1.aspx to saveXML.aspx . Then, after adding the two files ( customers.xml and editCustomer.htm ), the Solution Explorer will look like Figure 5.6. Look at the saveXML.aspx in the next section to see the code for the customers.xml and editCustomer.htm files.

Figure 5.6. The Solution Explorer for the CSMSXML project.
graphics/05fig06.gif

In this example, you use the following customers.xml document with three customer elements:

 <?xml version="1.0" encoding="utf-8" ?>  <!DOCTYPE Customers [      <!ELEMENT Customers (Customer)* >       <!ELEMENT Customer (CompanyName,Contact)  >       <!ATTLIST Customer                 id  CDATA  #REQUIRED >       <!ELEMENT CompanyName (#PCDATA)  >       <!ELEMENT Contact (FirstName , LastName , Title)  >       <!ELEMENT FirstName (#PCDATA)  >        !ELEMENT LastName (#PCDATA)  >       <!ELEMENT Title (#PCDATA)  >  ]>  <Customers>       <Customer id="ALFKI">            <CompanyName>Alfreds Futterkiste</CompanyName>            <Contact>                 <FirstName>Maria</FirstName>                 <LastName>Anders</LastName>                 <Title>Sales Representative</Title>            </Contact>       </Customer>       <Customer id="THEBI">            <CompanyName>The Big Cheese</CompanyName>            <Contact>                 <FirstName>Liz</FirstName>                 <LastName>Nixon</LastName>                 <Title>Marketing Manager</Title>            </Contact>       </Customer>       <Customer id="EASTC">            <CompanyName>Eastern Connection</CompanyName>            <Contact>                 <FirstName>Ann</FirstName>                 <LastName>Devon</LastName>                 <Title>Sales Agent</Title>            </Contact>       </Customer>  </Customers> 

Listing 5.6 shows the HTML file editCustomer.htm that sequentially performs the tasks of inserting, updating, and deleting nodes from an XML document loaded into the DOM. This is achieved by making calls to separate methods that implement respective functionality. These calls are interspersed with calls to a method that displays the current state of the documents in the DOM so that you can see the results after each operation. Note that we will discuss each part in Listing 5.6 separately instead of providing a continuous listing, which makes it too difficult to follow.

Listing 5.6 Inserting, Updating, and Deleting Nodes ( editCustomer.htm )
 <html>       <head>            <title>Insert, Update, Delete</title>       </head>       <body>            <form name="modify" method="post" ID="Form1">                 <div id="customers">                 </div>                 <INPUT type="hidden" name="customerData" value="" ID="Hidden1"> <INPUT graphics/ccc.gif type="button" value="Save XML" onclick="saveXML()" ID="Button1" NAME="Button1">            </form>       </body>  </html>  <script language="javascript">  var objXML = new ActiveXObject("MSXML2.DOMDocument");  objXML.async = false;  objXML.load("customers.xml");  var objDocElement = objXML.documentElement;  displayCustomers("After Loading");  var newCustNode = createCustomerNode("PARIS","Paris  spcialits","Marie","Bertrand","Owner");  insertNewCustomer(newCustNode, "THEBI");  displayCustomers("After insertion");  updateContact(findCustomer("ALFKI"),"Mario","Pontes","Accounting Manager");  displayCustomers("After Updating");  deleteCustomer("EASTC");  displayCustomers("After Deletion");  function displayCustomers(strHeading)   {      var custNode;       var contactNode;       var nodeList =   objXML.getElementsByTagName("Customer");       var strHTML = "<B>" + strHeading + "...</B>";       strHTML += "<table border='1'><thead><th>CustomerID</th><th>Company Name</th>" +                    "<th>Contact Name</th><th>Contact Title </th></thead><tbody>";       for (var i=0; i< nodeList.length ; i++)       {           custNode = nodeList.item(i);            strHTML += "<tr>" ;            strHTML += "<td>" + custNode.getAttribute("id") + "</td>" ;            strHTML += "<td>" + custNode.childNodes.item(0).text + "</td>";            contactNode = custNode.childNodes.item(1);            strHTML += "<td>" + contactNode.childNodes.item(0).text  ;            strHTML += " "    + contactNode.childNodes.item(1).text + "</td>";            strHTML += "<td>" + contactNode.childNodes.item(2).text + "</td>" ;            strHTML += "</tr>";       }       customers.innerHTML += strHTML + "</tbody></table>" ;  }  function createCustomerNode(customerID , companyName , contactFirstName ,                 contactLastName , contactTitle)   {      var custNode     = objXML.createElement("Customer");       var idAttr          = objXML.createAttribute("id");       idAttr.value    = customerID;       custNode.setAttributeNode(idAttr);       custNode.appendChild(createElement("CompanyName", companyName));       var contactNode = objXML.createElement("Contact");       contactNode.appendChild(createElement("FirstName", contactFirstName));       contactNode.appendChild(createElement("LastName", contactLastName));       contactNode.appendChild(createElement("Title", contactTitle));       custNode.appendChild(contactNode);       return custNode;  }  function insertNewCustomer(custNode, beforeID)  {      var nextCustNode = objXML.selectSingleNode("/Customers/Customer[@id='" + beforeID + graphics/ccc.gif "']");       if(nextCustNode==null)       {           alert("The Customer node with the id '"+ beforeID +"' was not found");            return;       }       objXML.documentElement.insertBefore(custNode , nextCustNode) ;        //performing runtime validation of the document to handle the error resulting out graphics/ccc.gif of the insertion of new node        var parseError = objXML.validate();        if(parseError != 0)        {           alert(parseError.reason);            //roll back on the latest insertion            objXML.documentElement.removeChild(custNode);        }  }  function createElement(elementName , text)  {      var elementNode = objXML.createElement(elementName);       var textNode = objXML.createTextNode(text);       elementNode.appendChild(textNode);       return elementNode;  }  function createClonedNode(customerID , companyName , contactFirstName ,            contactLastName , contactTitle)  {      var custNode     = objDocElement.firstChild.cloneNode(true);       //make deep copy       custNode.setAttribute("id" , customerID);       custNode.firstChild.text = companyName;       updateContact(custNode , contactFirstName , contactLastName , contactTitle);       return custNode;  }  function findCustomer(customerID)  {      var custNode =   objDocElement.firstChild;       while(custNode!=null)       {           if(custNode.getAttribute("id")== customerID)            {                return custNode;            }            custNode = custNode.nextSibling;       }  }  function updateContact(custNode , contactFirstName , contactLastName , contactTitle)  {      if(custNode == null)       {           alert("The Customer node with the id '"+ customerID +"' was not found");            return;       }       contactNode = custNode.getElementsByTagName("Contact").item(0);       contactNode.childNodes.item(0).text = contactFirstName;       contactNode.childNodes.item(1).text = contactLastName;       contactNode.childNodes.item(2).text = contactTitle;  }  function deleteCustomer(customerID)  {      var custNode = findCustomer(customerID);       if(custNode == null)       {           alert("The Customer node with the id '"+ customerID +"' was not found");            return;       }       objDocElement.removeChild(custNode);  }  function saveXML()  {      document.modify.customerData.value = objXML.xml;       document.modify.action = "saveXML.aspx";       document.modify.submit();  }  </script> 

We then call a sequence of methods to insert a new Customer node, update a node, delete a node, and intermittently call the method displayCustomers() , which displays the latest state of the document. The following code shows the implementation of the method displayCustomers() :

 function displayCustomers(strHeading)   {      var custNode       var contactNode       var nodeList =   objXML.getElementsByTagName("Customer")       var strHTML = "<B>" + strHeading + "...</B>"       strHTML += "<table border='1'><thead><th>CustomerID</th><th>Company Name</th>" +                    "<th>Contact Name</th><th>Contact Title</th></thead><tbody>"       for (var i=0; i< nodeList.length ; i++)       {           custNode = nodeList.item(i)            strHTML += "<tr>" ;            strHTML += "<td>" + custNode.getAttribute("id") + "</td>" ;            strHTML += "<td>" + custNode.childNodes.item(0).text + "</td>";            contactNode = custNode.childNodes.item(1) ;            strHTML += "<td>" + contactNode.childNodes.item(0).text  ;            strHTML += " "    + contactNode.childNodes.item(1).text + "</td>";            strHTML += "<td>" + contactNode.childNodes.item(2).text + "</td>" ;            strHTML += "</tr>";       }       customers.innerHTML += strHTML + "</tbody></table>" ;  } 

The displayCustomers method shows how to transform XML into HTML by using DOM. You see how to do this same transformation using XSLT and SAX later in this chapter.

You can use the getElementsByTagName method of the DOMDocument object. This returns an IXMLDOMNodeList object, a collection of elements that have the name Customer in the document. The IXMLDOMElement interface exposes the same method, but it only returns descendant elements, not all the elements that were encountered in the document (see the updateContact method shown in the following code). Navigate through this collection by using the ordinal index. Because you are aware of the document's structure, use the index to find the appropriate child nodes of the Customer node. You find the text of the elements by using the text property, which is an MSXML extension of the DOM.

The remaining code shows the implementation of the different operations:

 function createCustomerNode(customerID , companyName , contactFirstName ,                                contactLastName , contactTitle)   {           var custNode     = objXML.createElement("Customer")            var idAttr          = objXML.createAttribute("id")            idAttr.value    = customerID            custNode.setAttributeNode(idAttr)            custNode.appendChild(createElement("CompanyName" , companyName))            var contactNode = objXML.createElement("Contact")            contactNode.appendChild(createElement("FirstName" , contactFirstName))            contactNode.appendChild(createElement("LastName" , contactLastName))            contactNode.appendChild(createElement("Title" , contactTitle))            custNode.appendChild(contactNode)            return custNode  }  function insertNewCustomer(custNode ,  beforeID)  {      var nextCustNode = objXML.selectSingleNode("/Customers/Customer[@id='" + beforeID + graphics/ccc.gif "']")       if(nextCustNode==null)       {           alert("The Customer node with the id '"+ beforeID +"' was not found")            return;       }       objXML.documentElement.insertBefore(custNode , nextCustNode)        //performing runtime validation of the document to handle the error        //resulting out of        //the insertion of new node        var parseError = objXML.validate()        if(parseError != 0)        {           alert(parseError.reason)            //roll back on the latest insertion            objXML.documentElement.removeChild(custNode)        }  }  function createElement(elementName , text)  {           var elementNode = objXML.createElement(elementName)            var textNode = objXML.createTextNode(text)            elementNode.appendChild(textNode)            return elementNode  }  function createClonedNode(customerID , companyName , contactFirstName ,                           contactLastName , contactTitle)  {           var custNode = objDocElement.firstChild.cloneNode(true)            //make deep copy            custNode.setAttribute("id" , customerID)            custNode.firstChild.text = companyName            updateContact(custNode , contactFirstName , contactLastName , contactTitle)            return custNode  }  function findCustomer(customerID)  {           var custNode =   objDocElement.firstChild            while(custNode!=null)            {                if(custNode.getAttribute("id")== customerID)                 {                     return custNode                 }                 custNode = custNode.nextSibling            }  }  function updateContact(custNode , contactFirstName , contactLastName , contactTitle)  {           if(custNode == null)            {                 alert("The Customer node with the id '"+ customerID +"' was not found")                  return             }            contactNode = custNode.getElementsByTagName("Contact").item(0)            contactNode.childNodes.item(0).text = contactFirstName            contactNode.childNodes.item(1).text = contactLastName            contactNode.childNodes.item(2).text = contactTitle  }  function deleteCustomer(customerID)  {           var custNode = findCustomer(customerID)            if(custNode == null)            {                alert("The Customer node with the id '"+ customerID +"' was not found")                 return            }            objDocElement.removeChild(custNode)  }  function saveXML()  {      document.modify.customerData.value = objXML.xml       document.modify.action = "saveXML.aspx"       document.modify.submit()  }  </script> 

The createCustomerNode method demonstrates the creation of new content by using a set of the createXXX methods on the DOMDocument object. Alternatively, you can call the createClonedNode() method , which is mentioned in the previous code, to create the new node. This method clones an existing node by making a detailed copy of it and then updates the values of the created node to make a new node. This method is more efficient than the createXXX methods.

The insertNewCustomer method inserts the newly created node before the customer element with a specified value for the id attribute. It uses the selectSingleNode to search the specified node. This method takes an XSL query and performs the pattern-matching operation to the content of the node that's specified by the query and returns the first matching node. You will see how to use the XPath query language with this method in the section, "Selecting Nodes with XPath 1.0." Next, the insertNewCustomer method performs runtime validation on the document to handle the errors resulting from the insertion of new nodes.

You can extend the functionality that you saw in createCustomerNode to build an entire XML document from scratch. The following code shows how to start creating this document:

 var rootElement = objXML.createElement("Customers");  objXML.documentElement =  rootElement;  var  pi = objXML.createProcessingInstruction("xml", "version=\"1.0\"");  objXML.insertBefore(pi, objXML.childNodes.item(0)); 

The previous code will be complete as you append the customer nodes that are returned to the documentElement by the createCustomerNode function.

The updateContact method updates the values of the node passed to it. The deleteCustomer deletes the node from the DOM by using the removeChild method on the documentElement . Figure 5.7 shows the state of the document before and after each of the operations on the document.

Figure 5.7. The document's state before and after the insert, update, and delete operations.
graphics/05fig07.gif

Clicking the Save button posts the XML data to the saveXML.aspx page in the form of a string that's assigned to a hidden variable. The next section looks at the saveXML.aspx page and how you can save this XML data to the web server.

So far, you have seen the workings of MSXML in the client browser using JavaScript. From this point on, the focus shifts to the server-side use of MSXML with ASP.NET.

only for RuBoard


XML and ASP. NET
XML and ASP.NET
ISBN: B000H2MXOM
EAN: N/A
Year: 2005
Pages: 184

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net