XML
  Home arrow XML arrow Page 3 - XML Parsing With SAX and Xerces (part ...
Dev Shed Forums 
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Sun Developer Network 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Actuate Whitepapers 
Moblin 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
XML

XML Parsing With SAX and Xerces (part 2)
By: icarus, (c) Melonfire
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 1
    2002-02-12

    Table of Contents:
  • XML Parsing With SAX and Xerces (part 2)
  • The Write Stuff
  • Nailing It To The Wall
  • When Things Go Wrong
  • Endnote

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT

    Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here

    XML Parsing With SAX and Xerces (part 2) - Nailing It To The Wall


    (Page 3 of 5 )

    Now, how about something a little more useful? Consider the following modification of the previous example:

    <?xml version="1.0"?> <inventory> <item> <id>758</id> <name>Rusty, jagged nails for nailgun</name> <supplier>NailBarn, Inc.</supplier> <cost>2.99</cost> <quantity alert="500">10000</quantity> </item> <item> <id>6273</id> <name>Power pack for death ray</name> <supplier>QuakePower.domain.com</supplier> <cost currency="USD">9.99</cost> <quantity alert="20">10</quantity> </item> <item> <id>3784</id> <name>Axe</name> <supplier>Axe And You Shall Receive, Inc.</supplier> <cost currency="USD">56.74</cost> <quantity alert="5">25</quantity> </item> <item> <id>986</id> <name>NVGs</name> <supplier>Quake Eyewear</supplier> <cost currency="USD">1399.99</cost> <quantity alert="5">2</quantity> </item> </inventory>
    Now, let's suppose I want to display this information in a neatly-formatted table, with those items that I'm low on highlighted in red. My preferred output would look something like this:



    Here's the code to accomplish this:

    import org.apache.xerces.parsers.SAXParser; import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import java.io.*; public class MyFifthSaxApp extends DefaultHandler { private Writer out; private String ElementName, AttributeName,AttributeValue = ""; private Integer Quantity, Alert; // constructor public MyFifthSaxApp (String xmlFile, Writer out) throws SAXException { this.out = out; // Create a Xerces SAX parser SAXParser parser = new SAXParser(); // Set the Content Handler parser.setContentHandler(this); // parse the Document try { parser.parse(xmlFile); out.flush(); } catch (IOException e) { throw new SAXException(e); } } // call this when opening element found public void startElement (String uri, String local, String qName, Attributes atts) throws SAXException { try { // this is useful later ElementName = local; // display table header if(local.equals("inventory")) { out.write("<h1><font face=Verdana>Inventory Management</font></h1>n<table width="55%" cellpadding="5" cellspacing="5" border="1"><tr><td><p align=right><b><font face=Verdana size=2>Code</font></b></p></td><td><b><font face=Verdana size=2>Name</font></b></td><td><b><font face=Verdana size=2>Supplier</font></b></td><td><p align=right><b><font face=Verdana size=2>Cost</font></b></p></td><td><p align=right><font face=Verdana size=2><b>Quantity</b></font></p></td></tr>"); } else if(local.equals("item")) { // "item" element starts a new row out.write("<tr>"); } else if( local.equals("name") || local.equals("supplier")) { // create table cells within row // align strings left, numbers right out.write("<td><p align=left><font face=Verdana size=2>"); } else if( local.equals("id") || local.equals("cost") || local.equals("quantity")) { out.write("<td><p align=right><font face=Verdana size=2>"); } else { out.write("<br>"); } for (int i = 0; i < atts.getLength(); i++) { AttributeName = atts.getLocalName(i); AttributeValue = atts.getValue(AttributeName); if(AttributeName.equals("currency")) { out.write(AttributeValue + "&nbsp;"); } else if(AttributeName.equals("alert")) { Alert = new Integer(AttributeValue); } else { out.write("&nbsp;"); } } } catch (IOException e) { throw new SAXException(e); } } // call this when cdata found public void characters(char[] text, int start, int length) throws SAXException { try { String Content = new String(text, start, length); if (!Content.trim().equals("")) { if ((ElementName != null && ElementName.equals("quantity")) && (AttributeName != null && AttributeName.equals("alert"))) { Quantity = new Integer(Content); // if quantity lower than expected, highlight in red if((Quantity.intValue()) < (Alert.intValue())) { out.write("<font color="#ff0000">" + Quantity + "</font>"); } else { out.write("<font color="#000000">" + Quantity + "</font>"); } } else { out.write(Content); } } } catch (IOException e) { throw new SAXException(e); } } // call this when closing element found public void endElement (String uri, String local, String qName) throws SAXException { try { if(local.equals("inventory")) { out.write("</table>"); } else if(local.equals("item")) { // "item" closes table row out.write("</tr>"); } else if(local.equals("id") || local.equals("name") || local.equals("supplier") || local.equals("cost") || local.equals("quantity")) { // close table cells out.write("</font></p></td>"); } else { out.write("&nbsp;"); } } catch (IOException e) { throw new SAXException(e); } } }
    As you can see, the callback functions used here have evolved substantially from the previous examples - they now contain more conditional tests, and better error handling capabilities. Let's take a closer look.

    Most of the work in this script is done by the startElement() callback function. This function prints specific HTML output depending on the element encountered by the parser.

    // call this when opening element found public void startElement (String uri, String local, String qName, Attributes atts) throws SAXException { try { // this is useful later ElementName = local; // display table header if(local.equals("inventory")) { out.write("<h1><font face=Verdana>Inventory Management</font></h1>n<table width="55%" cellpadding="5" cellspacing="5" border="1"><tr><td><p align=right><b><font face=Verdana size=2>Code</font></b></p></td><td><b><font face=Verdana size=2>Name</font></b></td><td><b><font face=Verdana size=2>Supplier</font></b></td><td><p align=right><b><font face=Verdana size=2>Cost</font></b></p></td><td><p align=right><font face=Verdana size=2><b>Quantity</b></font></p></td></tr>"); } else if(local.equals("item")) { // "item" element starts a new row out.write("<tr>"); } else if( local.equals("name") || local.equals("supplier")) { // create table cells within row // align strings left, numbers right out.write("<td><p align=left><font face=Verdana size=2>"); } else if( local.equals("id") || local.equals("cost") || local.equals("quantity")) { out.write("<td><p align=right><font face=Verdana size=2>"); } else { out.write("<br>"); } for (int i = 0; i < atts.getLength(); i++) { AttributeName = atts.getLocalName(i); AttributeValue = atts.getValue(AttributeName); if(AttributeName.equals("currency")) { out.write(AttributeValue + "&nbsp;"); } else if(AttributeName.equals("alert")) { Alert = new Integer(AttributeValue); } else { out.write("&nbsp;"); } } } catch (IOException e) { throw new SAXException(e); } }
    This function maps different XML elements to appropriate HTML markup. As you can see, the document element "inventory", which marks the start of the XML document, is used to create the skeleton and first row of an HTML table, while the different "item" elements correspond to rows within this table. The details of each item - name, supplier, quantity et al - are formatted as cells within each row of the table.

    Next, the characters() callback function handles formatting of the content embedded within the elements.

    // call this when cdata found public void characters(char[] text, int start, int length) throws SAXException { try { String Content = new String(text, start, length); if (!Content.trim().equals("")) { if ((ElementName != null && ElementName.equals("quantity")) && (AttributeName != null && AttributeName.equals("alert"))) { Quantity = new Integer(Content); // if quantity lower than expected, highlight in red if((Quantity.intValue()) < (Alert.intValue())) { out.write("<font color="#ff0000">" + Quantity + "</font>"); } else { out.write("<font color="#000000">" + Quantity + "</font>"); } } else { out.write(Content); } } } catch (IOException e) { throw new SAXException(e); } }
    For most of the elements, I'm simply displaying the content as is. The only deviation from this standard policy occurs with the "quantity" element, which has an additional "alert" attribute. This "alert" attribute specifies the minimum number of units that should be in stock of the corresponding item; if the quantity drops below this minimum level, an alert should be generated. Consequently, the characters() callback includes some code to test the current quantity against the minimum quantity, and highlight the data in red if the test fails.

    And finally, to wrap things up, the endElement() callback closes the HTML tags opened earlier.

    // call this when closing element found public void endElement (String uri, String local, String qName) throws SAXException { try { if(local.equals("inventory")) { out.write("</table>"); } else if(local.equals("item")) { // "item" closes table row out.write("</tr>"); } else if(local.equals("id") || local.equals("name") || local.equals("supplier") || local.equals("cost") || local.equals("quantity")) { // close table cells out.write("</font></p></td>"); } else { out.write("&nbsp;"); } } catch (IOException e) { throw new SAXException(e); } }
    Once you've compiled this class, you can use it in a JSP page, as you did with the previous example. Here's the code,

    <%@ page language="java" import="java.io.IOException" %> <html> <head> </head> <body> <% try { MyFifthSaxApp myFifthExample = new MyFifthSaxApp("/www/xerces/WEB-INF/classes/inventory.xml",out); } catch (Exception e) { out.println("<font face="verdana" size="2">The following error occurred: <br><b>" + e + "</b></font>"); } %> </body> </html>
    and here's the output:

    More XML Articles
    More By icarus, (c) Melonfire


     

       

    XML ARTICLES

    - How to Set Up Podcasting and Vodcasting
    - Creating an RSS Reader Application
    - Building an RSS File
    - An Introduction to XUL Part 6
    - An Introduction to XUL Part 5
    - An Introduction to XUL Part 4
    - An Introduction to XUL Part 3
    - An Introduction to XUL Part 2
    - An Introduction to XUL Part 1
    - XML Matters: Practical XML Data Design and M...
    - Practical XML Data Design and Manipulation f...
    - SimpleXML
    - XForms Basics, Part 3
    - XForms Basics, Part 2
    - XForms Basics




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway