XML by Example- P7

Chia sẻ: Thanh Cong | Ngày: | Loại File: PDF | Số trang:50

0
51
lượt xem
12
download

XML by Example- P7

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tham khảo tài liệu 'xml by example- p7', công nghệ thông tin, kỹ thuật lập trình phục vụ nhu cầu học tập, nghiên cứu và làm việc hiệu quả

Chủ đề:
Lưu

Nội dung Text: XML by Example- P7

  1. Creating Documents Without DOM 285 var name = form.name.value, dollars = form.dollarsamount.value, euros = form.eurosamount.value, productList = form.productlist; // creates the various objects required var dollarsPrice = new Price(dollars,”usd”), eurosPrice = new Price(euros,”eur”), prices = new Array(dollarsPrice,eurosPrice), product = new Product(name,prices); // arrays are zero-based so products.length points // to one past the latest product // JavaScript automatically allocates memory var pos = products.length; products[pos] = product; var option = new Option(name,pos); productList.options[productList.length] = option; } function deleteProduct(form) { var productList = form.productlist, pos = productList.selectedIndex; if(pos != -1) { var product = productList.options[pos].value; productList.options[pos] = null; products[product] = null; } } function exportProduct(form) { continues
  2. 286 Chapter 9: Writing XML Listing 9.6: continued form.output.value = makeXML(); } function send() { var http = new ActiveXObject(“Microsoft.XMLHTTP”); http.open(“POST”,”http://catwoman.pineapplesoft.com/Dump”,false); http.setRequestHeader(“Content-type”,”application/xml”); http.send(“value=” + makeXML()); document.open(); document.write(http.responseText); } function makeXML() { var xmlCode = “”; var i; for(i = 0;i < products.length;i++) if(products[i] != null) xmlCode += products[i].toXML(); return element(“products”,””,xmlCode); } function resetAll(form,document) { priceList = null; form.output.value = “”; } function element(name,attributes,content) { var result = “”;
  3. Creating Documents Without DOM 287 result += content; result += “\r”; return result; } function escapeXML(string) { var result = “”, i, c; for(i = 0;i < string.length;i++) { c = string.charAt(i); if(c == ‘
  4. 288 Chapter 9: Writing XML Listing 9.6: continued i; for(i = 0;i < this.prices.length;i++) result += this.prices[i].toXML(); return element(“product”,””,result); } // price object function Price(amount,currency) { this.amount = amount; this.currency = currency; this.toXML = price_toXML; } function price_toXML() { return element(“price”, “currency=\”” + this.currency + “\””, escapeXML(this.amount)); } Because this application does not use DOM, it works with browsers that have no XML support (obviously, they need to support JavaScript), such as Netscape 4. Figure 9.3 shows the result in Netscape. OUTPUT A Non-DOM Data Structure This application is radically different from the other applications intro- duced in this chapter. Internally, the application does not use XML, but uses its own data structure instead. In other words, it does not create Element objects; it creates Product and Price JavaScript objects. In JavaScript, an object constructor is simply a function that sets the object properties. A method is a property that is assigned a function.
  5. Creating Documents Without DOM 289 Figure 9.3: The result in Netscape In this example, the constructor for Product declares two properties (name and prices) and one method (toXML). function Product(name,prices) { this.name = name; this.prices = prices; this.toXML = product_toXML; } These objects are created with the new operator like built-in JavaScript objects: var product = new Product(name,prices); JavaScript objects are used like built-in objects: xmlCode += products[i].toXML(); Writing XML The Product and Price objects are XML-aware because they know how to save (serialize) themselves as XML objects through the toXML() function. The makeXML() function is trivial: It iterates over the list of products calling EXAMPLE the toXML() function. It wraps the result in a products element: function makeXML() { var xmlCode = “”;
  6. 290 Chapter 9: Writing XML var i; for(i = 0;i < products.length;i++) if(products[i] != null) xmlCode += products[i].toXML(); return element(“products”,””,xmlCode); } Notice that this approach is recursive. Product implements its toXML() method partly by serializing the list of Price and wrapping it in a product element. function product_toXML() { var result = element(“name”,””,escapeXML(this.name)), i; for(i = 0;i < this.prices.length;i++) result += this.prices[i].toXML(); return element(“product”,””,result); } function price_toXML() { return element(“price”, “currency=\”” + this.currency + “\””, escapeXML(this.amount)); } XML is a convenient format because elements can nest in a way that is very similar to how objects are referenced by other objects. Hiding the Syntax This application needs to know very little about the XML syntax. Its knowl- edge is completely encapsulated in two functions—element() and escapeXML(). 1. element() is in charge of the tagging. Again, the core XML syntax function is simple and it shows in this function. function element(name,attributes,content) EXAMPLE { var result = “
  7. Creating Documents from Non-XML Data Structures 291 if(attributes != “”) result += “ “ + attributes; result += “>”; result += content; result += “\r”; return result; } 2. escapeXML() ensures that the angle bracket and ampersand characters are escaped. These characters are not allowed in the text of an ele- ment. function escapeXML(string) EXAMPLE { var result = “”, i, c; for(i = 0;i < string.length;i++) { c = string.charAt(i); if(c == ‘
  8. 292 Chapter 9: Writing XML TIP So, when do you use DOM and when do you write your own generator? I find that DOM is ideal for modifying existing documents. In most other cases, I prefer my own generator. Figure 9.4: Comparing DOM with an ad hoc generator Doing Something with the XML Documents Now that you can create XML documents, you probably want to do some- thing more involved than display the XML code in an HTML form. In most cases, the application can either save the document to a file or send it to a server. ✔ This section looks briefly at your options to save the document or send it to the server. We will revisit this topic in Chapter 12, “Putting It All Together: An e-Commerce Example,” (page 381). Sending the Document to the Server There are two options to send the document to the server. You can place the XML document in an HTML form and have it sent along with the form, you can use a JavaBean or an ActiveX control to post the XML document to the Web server. 1. Sending the XML document in a form is the most portable approach. Because you already create the XML document in a form, this is easy to do. The FORM tag needs an ACTION attribute and the INPUT field must be changed from BUTTON to SUBMIT. You might also want to change the TEXTAREA in a HIDDEN field so XML does not appear onscreen:
  9. Doing Something with the XML Documents 293 Listing 9.8: HTML Form to Send the Document Product name: Price (Dollars): Price (Euros): The Web server will receive the XML document in a parameter called “out- put.” You would have to write a servlet or a CGI script to retrieve the docu- ment on the Web server. The beauty of this approach is that the document is returned in a form so the servlet simply accesses form parameters to retrieve the XML document. ✔ The section “Viewer and Editor” in Chapter 12 (page 444) shows such a servlet. CAUTION This example uses the Dump service that comes standard with Jetty, the Web server. Dump replies with a document that contains whatever it originally received. It is conve- nient for testing. If you don’t use Jetty, you will need to write your own servlet to accept the XML docu- ment. ✔ The section “Servlet Engine” in Appendix A explains how to install Jetty (page 460). Alternatively, you can post the data directly to the Web server, without going through a form. This method has the added benefit of not changing the current page. However, you have to go through an ActiveX object
  10. 294 Chapter 9: Writing XML (Internet Explorer), a plug-in (all browsers), or a JavaBean (all browsers, all platforms). 2. Internet Explorer 5.0 ships with XMLHTTP, an ActiveX control that can send XML documents from JavaScript. Listing 9.9 shows how to use XMLHTTP. EXAMPLE Listing 9.9: Posting the Result on a Web Site function send() { var http = new ActiveXObject(“Microsoft.XMLHTTP”); http.open(“POST”,”http://catwoman.pineapplesoft.com/Dump”,false); http.setRequestHeader(“Content-type”,”application/xml”); http.send(makeXML()); document.open(); document.write(http.responseText); } The ActiveX object has the following methods: • open(protocol,url,asynchronous) connects to a url. Set the protocol to POST. Set asynchronous to false to send synchronously. • setRequestHeader(keyword,value) adds a new keyword in the header of the document; you must use this function to set the content-type. • send(data) posts the data to the server. You need to change the “Send in XML” button in Listing 9.9 to call this function: Again, you need a servlet or CGI script on the server to receive the XML document. The URL http://catwoman.pineapplesoft.com/Dump points the Dump ser- vice on my machine. You will need to change this URL to your Web server. Listing 9.10 is a typical response from the server. OUTPUT TIP Jetty’s Dump returns an HTML document that contains the POST parameters. Choose “View Source” in your browser options to see the XML document. Listing 9.10: XML Document Returned by the Server XML Editor 499.00 475.00
  11. Doing Something with the XML Documents 295 DTD Editor 199.00 190 XML Book 19.99 19.00 XML Training 699.00 666.00 Saving the Document JavaScript applications cannot access the local hard disk unless they have been signed. Therefore, it is not common to save the XML in a file on a browser. However, on the server, you often want to save XML documents. If you cre- ated the file with your own generator, you save it like any other file. When creating a document with a Microsoft DOM parser, you use a Microsoft-specific extension to save the document. Microsoft parser sup- ports the save() function. However, as I have just explained, this extension does not work on the browser. It is therefore only useful when writing CGI scripts or ASP pages. The example in Listing 9.11 shows how to save a file from JavaScript in an ASP server. Listing 9.11: Saving the XML Document
  12. 296 Chapter 9: Writing XML NOTE To create an XML parser from ASP you cannot use an XML island. Instead create the , XML parser directly as an ActiveXObject as in var xmldoc = new ActiveXObject(“Microsoft.XMLDOM”); This is equivalent to creating an XML island on a browser. Writing with Flexibility in Mind One of the major advantages of XML is that it is extensible. Anyone can create a tagging language with tags specific to the application. On the other hand, it means applications must be able to support different DTDs. For example, your company can have its own DTDs for internal exchange. However, when exchanging documents with other companies, you may have to use another DTD. There are also so-called standard DTDs developed by various standardiza- tion committees. In fact, developing DTDs has become a favorite activity in standard bodies lately, so expect more in the future. Unfortunately, so many committees are actively developing standards that you may have to support several incompatible standards. There are essentially two solutions to this problem. Either you define sev- eral toXML() functions, one for each DTD that you want to support, or you turn to XSLT. In most cases, I would advocate using XSLT. It is a waste of time to write as many functions as there are DTDs. XSLT is also more flexible because you don’t have to write code to add new DTDs or when a DTD changes (and it happens more often than you might think). Supporting Several DTDs with XSLT Listings 9.12 and 9.13 show how to use XSLT to support several DTDs. The user chooses the DTD from a list box. Unlike the previous version, this version uses the XSL processor of Internet Explorer. It will not run on EXAMPLE Netscape. TIP If you need to support both browsers, you can replace the Internet Explorer XSL proces- sor with LotusXSL. LotusXSL comes with several examples that show how to use it in a browser. However, it is not as stable as using the built-in XSL processor. If at all possible, stick to Internet Explorer.
  13. Writing with Flexibility in Mind 297 Listing 9.12: The HTML Code Price List Editor Product name: Price (Dollars): Price (Euros): products price-list
  14. 298 Chapter 9: Writing XML Listing 9.13: The JavaScript Code var products = new Array(); function addProduct(form) { // collects data from the form var name = form.name.value, dollars = form.dollarsamount.value, euros = form.eurosamount.value, productList = form.productlist; // creates the various objects required var dollarsPrice = new Price(dollars,”usd”), eurosPrice = new Price(euros,”eur”), prices = new Array(dollarsPrice,eurosPrice), product = new Product(name,prices); // arrays are zero-based so products.length points // to one past the latest product // JavaScript automatically allocates memory var pos = products.length; products[pos] = product; var option = new Option(name,pos); productList.options[productList.length] = option; } function deleteProduct(form) { var productList = form.productlist, pos = productList.selectedIndex; if(pos != -1) { var product = productList.options[pos].value; productList.options[pos] = null; products[product] = null;
  15. Writing with Flexibility in Mind 299 } } function exportProduct(form,xml,xslt) { var selected = form.format.selectedIndex, format = form.format.options[selected].value; if(format == “default”) form.output.value = makeXML(); else { var xmlDoc = makeXML(); xml.async = false; // passes an XML string to the parser xml.loadXML(xmlDoc); form.output.value = xml.transformNode(xslt.XMLDocument); } } function send() { var http = new ActiveXObject(“Microsoft.XMLHTTP”); http.open(“POST”,”http://catwoman.pineapplesoft.com/Dump”,false); http.setRequestHeader(“Content-type”,”application/xml”); http.send(“value=” + makeXML()); document.open(); document.write(http.responseText); } function makeXML() { var xmlCode = “”; var i; for(i = 0;i < products.length;i++) if(products[i] != null) continues
  16. 300 Chapter 9: Writing XML Listing 9.13: continued xmlCode += products[i].toXML(); return element(“products”,””,xmlCode); } function resetAll(form,document) { priceList = null; form.output.value = “”; } function element(name,attributes,content) { var result = “”; result += content; result += “\r”; return result; } function escapeXML(string) { var result = “”, i, c; for(i = 0;i < string.length;i++) { c = string.charAt(i); if(c == ‘
  17. Writing with Flexibility in Mind 301 return result; } // declares two JavaScript objects // product object function Product(name,prices) { this.name = name; this.prices = prices; this.toXML = product_toXML; } function product_toXML() { var result = element(“name”,””,escapeXML(this.name)), i; for(i = 0;i < this.prices.length;i++) result += this.prices[i].toXML(); return element(“product”,””,result); } // price object function Price(amount,currency) { this.amount = amount; this.currency = currency; this.toXML = price_toXML; } function price_toXML() { return element(“price”, “currency=\”” + this.currency + “\””, this.amount); }
  18. 302 Chapter 9: Writing XML The application outputs a default XML format. The style sheet in Listing 9.14 does the conversion. Obviously, it is an Internet Explorer style sheet. As explained in Chapter 5, “XSL Transformation,” this style sheet is not strictly compliant with the standard but it would not take too much work to adapt it. Listing 9.14: The Style Sheet ➥ ➥ ➥
  19. Writing with Flexibility in Mind 303 Figures 9.5 and 9.6 illustrate the difference between the two DTDs. Figure 9.5 is the structure created so far—it is a complex structure with several levels of nesting. Figure 9.6, on the other hand, has a flat structure. Figure 9.5: The default structure Figure 9.6: The new structure Figures 9.7 and 9.8 show the difference when selecting one or the other out- put format in the browser. OUTPUT Figure 9.7: Default output format Figure 9.8: New output format Calling XSLT The major difference between this application and the previous one is the exportProduct() function. exportProduct() calls makeXML() to generate the XML document. Depending on the user choice, it may apply an XSLT style EXAMPLE sheet to the result. function exportProduct(form,xml,xslt) { var selected = form.format.selectedIndex, format = form.format.options[selected].value; if(format == “default”) form.output.value = makeXML();
  20. 304 Chapter 9: Writing XML else { var xmlDoc = makeXML(); xml.async = false; // passes an XML string to the parser xml.loadXML(xmlDoc); form.output.value = xml.transformNode(xslt.XMLDocument); } } Unfortunately, the DOM standard does not specify how to apply an XSLT style sheet to a document. Again, you can use a browser-specific extension. For Internet Explorer, the XSL processor is called by the transformNode() method. The XSLT style sheet was loaded in a separate XML island. Which Structure for the Document? If your application supports several DTDs, you may wonder which one to use as the default DTD. Experience shows that it pays to be dumb when designing this default DTD. I like to define a DTD that is very similar to my object structure. So, if the application has Product and Price objects, I create two elements: product and price. There are two main advantages to designing a DTD that is close to the internal data structure: • It is easy to generate the XML document. • The resulting document is as expressive as the internal data struc- ture. XSLT Versus Custom Functions XSLT has been designed specifically to convert XML documents. It offers a simple solution to cleanly separate the DTD from the application code. This separation of roles offers many advantages: • If the format changes, you don’t have to change your application, only the style sheet.
Đồng bộ tài khoản