Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 53 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
53
Dung lượng
303,81 KB
Nội dung
if(args.length < 2) { System.out.println(“java com.psol.xbe.BestDeal filename delivery”); return; } ComparingMachine comparingMachine = new ComparingMachine(Integer.parseInt(args[1])); SAX2Internal sax2Internal = new SAX2Internal(comparingMachine); try { Parser parser = ParserFactory.makeParser(PARSER_NAME); parser.setDocumentHandler(sax2Internal); parser.parse(args[0]); } catch(SAXException e) { Exception x = e.getException(); if(null != x) throw x; else throw e; } System.out.println(“The best deal is proposed by “ + comparingMachine.getVendor()); System.out.println(“a “ + comparingMachine.getProductName() + “ at “ + comparingMachine.getPrice() + “ delivered in “ + comparingMachine.getDelivery() + “ days”); } } 250 Chapter 8: Alternative API: SAX Listing 8.4: continued 10 2429 CH08 11/12/99 1:09 PM Page 250 /** * This class receives events from the SAX2Internal adapter * and does the comparison required. * This class holds the “business logic.” */ class ComparingMachine { /** * properties we are collecting: best price */ protected double bestPrice = Double.MAX_VALUE; /** * properties we are collecting: delivery time */ protected int proposedDelivery = Integer.MAX_VALUE; /** * properties we are collecting: product and vendor names */ protected String productName = null, vendorName = null; /** * target delivery value (we refuse elements above this target) */ protected int targetDelivery; /** * creates a ComparingMachine * @param td the target for delivery */ public ComparingMachine(int td) { targetDelivery = td; } 251 Maintaining the State continues 10 2429 CH08 11/12/99 1:09 PM Page 251 /** * called by SAX2Internal when it has found the product name * @param name the product name */ public void setProductName(String name) { productName = name; } /** * called by SAX2Internal when it has found a price * @param vendor vendor’s name * @param price price proposal * @param delivery delivery time proposal */ public void compare(String vendor,double price,int delivery) { if(delivery <= targetDelivery) { if(bestPrice > price) { bestPrice = price; vendorName = vendor; proposedDelivery = delivery; } } } /** * property accessor: vendor’s name * @return the vendor with the cheapest offer so far */ public String getVendor() { return vendorName; } 252 Chapter 8: Alternative API: SAX Listing 8.4: continued 10 2429 CH08 11/12/99 1:09 PM Page 252 /** * property accessor: best price * @return the best price so far */ public double getPrice() { return bestPrice; } /** * property accessor: proposed delivery * @return the proposed delivery time */ public int getDelivery() { return proposedDelivery; } /** * property accessor: product name * @return the product name */ public String getProductName() { return productName; } } /** * SAX event handler to adapt from the SAX interface to * whatever the application uses internally. */ class SAX2Internal extends HandlerBase { /** 253 Maintaining the State continues 10 2429 CH08 11/12/99 1:09 PM Page 253 * state constants */ final protected int START = 0, PRODUCT = 1, PRODUCT_NAME = 2, VENDOR = 3, VENDOR_NAME = 4, VENDOR_PRICE = 5; /** * the current state */ protected int state = START; /** * current leaf element and current vendor */ protected LeafElement currentElement = null, currentVendor = null; /** * BestDeal object this event handler interfaces with */ protected ComparingMachine comparingMachine; /** * creates a SAX2Internal * @param cm the ComparingMachine to interface with */ public SAX2Internal(ComparingMachine cm) { comparingMachine = cm; } /** * startElement event * @param name element’s name 254 Chapter 8: Alternative API: SAX Listing 8.4: continued 10 2429 CH08 11/12/99 1:09 PM Page 254 * @param attributes element’s attributes */ public void startElement(String name,AttributeList attributes) { // this accepts many combinations of elements // it would work if new elements where being added, etc. // this ensures maximal flexibility: if the document // has to be validated, a validating parser does it switch(state) { case START: if(name.equals(“product”)) state = PRODUCT; break; case PRODUCT: if(name.equals(“name”)) { state = PRODUCT_NAME; currentElement = new LeafElement(name,attributes); } if(name.equals(“vendor”)) state = VENDOR; break; case VENDOR: if(name.equals(“name”)) { state = VENDOR_NAME; currentElement = new LeafElement(name,attributes); } if(name.equals(“price”)) { state = VENDOR_PRICE; currentElement = new LeafElement(name,attributes); } break; } } 255 Maintaining the State continues 10 2429 CH08 11/12/99 1:09 PM Page 255 /** * content of the element * @param chars documents characters * @param start first character in the content * @param length last character in the content */ public void characters(char[] chars,int start,int length) { switch(state) { case PRODUCT_NAME: case VENDOR_NAME: case VENDOR_PRICE: currentElement.append(chars,start,length); break; } } /** * endElement event * @param name element’s name */ public void endElement(String name) { switch(state) { case PRODUCT_NAME: if(name.equals(“name”)) { state = PRODUCT; comparingMachine.setProductName( currentElement.getText()); } break; case VENDOR: if(name.equals(“vendor”)) 256 Chapter 8: Alternative API: SAX Listing 8.4: continued 10 2429 CH08 11/12/99 1:09 PM Page 256 state = PRODUCT; break; case VENDOR_NAME: if(name.equals(“name”)) { state = VENDOR; currentVendor = currentElement; } break; case VENDOR_PRICE: if(name.equals(“price”)) { state = VENDOR; double price = toDouble(currentElement.getText()); Dictionary attributes = currentElement.getAttributes(); String stringDelivery = (String)attributes.get(“delivery”); int delivery = Integer.parseInt(stringDelivery); comparingMachine.compare(currentVendor.getText(), price, delivery); } break; } } /** * helper method: turn a string in a double * @param string number as a string * @return the number as a double, or 0.0 if it cannot convert * the number */ protected double toDouble(String string) { Double stringDouble = Double.valueOf(string); if(null != stringDouble) 257 Maintaining the State continues 10 2429 CH08 11/12/99 1:09 PM Page 257 return stringDouble.doubleValue(); else return 0.0; } } /* * helper class: used to store a leaf element content */ class LeafElement { /** * property: element’s name */ protected String name; /** * property: element’s attributes */ protected Dictionary attributes; /** * property: element’s text */ protected StringBuffer text = new StringBuffer(); /** * creates a new element * @param n element’s name * @param a element’s attributes */ public LeafElement(String n,AttributeList al) { name = n; attributes = new Hashtable(); for(int i = 0;i < al.getLength();i++) attributes.put(al.getName(i),al.getValue(i)); 258 Chapter 8: Alternative API: SAX Listing 8.4: continued 10 2429 CH08 11/12/99 1:09 PM Page 258 } /** * append to the current text * @param chars array of characters * @param start where to start in chars * @param length how many characters to consider in chars */ public void append(char[] chars,int start,int length) { text.append(chars,start,length); } /** * property accessor: text */ public String getText() { return text.toString(); } /** * property accessor: name */ public String getName() { return name; } /** * property accessor: attributes */ public Dictionary getAttributes() { return attributes; } } 259 Maintaining the State 10 2429 CH08 11/12/99 1:09 PM Page 259 [...]... -classpath c: \xml4 j \xml4 j.jar;classes com.psol.xbe.BestDeal ➥product .xml 60 returns The best deal is proposed by XMLi a XML Training at 69 9.0 delivered in 45 days whereas java -classpath c: \xml4 j \xml4 j.jar;classes com.psol.xbe.BestDeal ➥product .xml 3 returns The best deal is proposed by Emailaholic a XML Training at 1999.0 delivered in 2 days A Layered Architecture Listing 8.4 is the most complex application... you learned how to read XML documents In the next chapter, you learn how to write documents, thereby closing the loop 10 2429 CH08 11/12/99 1:09 PM Page 267 11 2429 CH09 11/12/99 1:02 PM Page 268 11 2429 CH09 11/12/99 1:02 PM Page 269 9 Writing XML In the last four chapters, you learned how to use XML documents in your applications You studied style sheets and how to convert XML documents in HTML You... 260 260 Chapter 8: Alternative API: SAX OUTPUT You compile and run this application just like the “Cheapest” application introduced previously The results depend on the urgency of the delivery You will notice that this program takes two parameters: the filename and the longest delay java -classpath c: \xml4 j \xml4 j.jar;classes com.psol.xbe.BestDeal ➥product .xml 60 returns The best deal is proposed by. .. Writing XML Listing 9.3: JavaScript Code function convert(form,xmldocument) { var fname = form.fname.value, output = form.output, rate = form.rate.value; output.value = “”; var document = parse(fname,xmldocument), topLevel = document.documentElement; walkNode(topLevel,document,rate); addHeader(document,rate); output.value = document .xml; } function parse(uri,xmldocument) { xmldocument.async = false; xmldocument.load(uri);... added Saving As XML Unfortunately, the current DOM recommendation does not specify how to retrieve the actual XML markup from the XML island In the Microsoft implementation, the Document object has an xml property EXAMPLE var document = parse(fname,xmldocument), topLevel = document.documentElement; walkNode(topLevel,document,rate); addHeader(document,rate); output.value = document .xml; CAUTION Theoretically,... writing XML documents DOM objects have methods to support creating or modifying XML documents Listing 9.1 is the XML price list used in Chapter 7 EXAMPLE ✔ The example in the section “A DOM Application” in Chapter 7 (page 199) converted the prices into Euros and printed the result With small changes to the original application, you can record the new prices in the original document Listing 9.1: XML Price... TYPE=”BUTTON” VALUE=”Create” ONCLICK=”create(controls ,xml) ”> < /xml> 11 2429 CH09 11/12/99 1:02 PM Page 280 280 Chapter 9: Writing XML Listing 9.5: JavaScript to Create a Document... Page 2 76 2 76 Chapter 9: Writing XML 2 While modifying the document, it is easy to attach a style sheet to it The addHeader() function appends a small header at the beginning of the document with a style sheet and a comment EXAMPLE function addHeader(document,rate) { var comment = document.createComment( “Rate used for this conversion: “ + rate), stylesheet = document.createProcessingInstruction( xml- stylesheet”,... Listing 9.1: XML Price List < ?xml version=”1.0”?> XML Editor 499.00 DTD Editor 199.00 XML Book 19.99 11 2429 CH09 11/12/99 1:02 PM Page 271 Modifying a Document with DOM 271 XML Training 69 9.00 ... constraints on the structure of the underlying document It simply ignores new elements For example, it would accept the following vendor element: EXAMPLE Playfield Training John Doe 10 2429 CH08 11/12/99 1:09 PM Page 266 266 Chapter 8: Alternative API: SAX 999.00 899.00 but it would ignore the contact . -classpath c: xml4 j xml4 j.jar;classes com.psol.xbe.BestDeal ➥product .xml 60 returns The best deal is proposed by XMLi a XML Training at 69 9.0 delivered in 45 days whereas java -classpath c: xml4 j xml4 j.jar;classes. to read XML documents. In the next chapter, you learn how to write documents, thereby closing the loop. 266 Chapter 8: Alternative API: SAX EXAMPLE 10 2429 CH08 11/12/99 1:09 PM Page 266 10 2429. Page 267 11 2429 CH09 11/12/99 1:02 PM Page 268 9 Writing XML In the last four chapters, you learned how to use XML documents in your applications. You studied style sheets and how to convert XML