Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 4 of 4
This process gives you a set of new classes that form the basis of a new SAX parser. They are located in your SAX generator's
output/ subdirectory. Assuming you used example1.xsd, you will have classes called CompanyHandler, EmployeesHandler, EmployeeHandler, and NameHandler.
To use the generated SAX parser, you must create an entry-point class instance, named Parser by default, and call the parse() method. Listing 5 shows you how to initiate the SAX parser:
Listing 5. Initiate the SAX parser
public static void main (String[] args) throws Exception
{
Parser parser = new Parser();
FileInputStream fis = new FileInputStream (args[0]);
parser.parse (fis);
}
At this stage, the newly generated classes do nothing; we must write implementations for the relevant methods. We must write
an implementation for the CompanyHandler class to print the company heading. Currently, the CompanyHandler class has only empty methods: The SAX parser calls this handler's start() method when it encounters the <company> element; the end() method executes when the closing </company> is parsed. The startEmployees() method executes when the parser enters an <employees> element.
In this case, we want to print the company name when the <company> element starts, so we must add code to the start() method. Note that the SAX generator has already declared local variables for the entity's attributes. After we add code to
print the header line, the method looks like this:
Listing 6. Print the company header
public void start (Attributes attributes) throws SAXException
{
String Name = attributes.getValue("Name");
System.out.println ("Employee Listing For "+Name);
System.out.println ();
}
Before we can print the employee information, we first must handle the <name> entity. Because this entity is complex, it has a separate handler class and needs some way to communicate name information
back to the EmployeeHandler class. For this purpose, I created a global map object, called params, which allows you to pass information from one handler to the other. The Parser class automatically creates this map for you; to use the map, you simply need to add some information to it.
Now we need to add the text data enclosed in the XML elements to the params map. To access an XML element's text content, use the getText() method. A utility method, getText() returns the text enclosed in an entity with leading and trailing white-space characters removed. The following code snippet
adds the text from <first> and <last> to the params map:
Listing 7. Add information to global params
public void endfirst () throws SAXException
{
params.put ("firstname",getText());
}
public void endlast () throws SAXException
{
params.put ("lastname",getText());
}
Now we can extract this information from the EmployeeHandler class. Because we must wait until the entire entity has been parsed (remember the <name> tag has to be handled before we print the employee information), we must add the following code to the end() method:
Listing 8. The employee handler
public void end () throws SAXException
{
String firstname = params.remove ("firstname").toString();
String lastname = params.remove ("lastname").toString();
System.out.println (office + "\t " + firstname + "\t" + lastname +
"\t" + telephone);
}
If you need to do some processing, depending on the context in which an element occurs, you can use the Path object to find the current entity's context. Path is a stack containing the path of element names from the root element to the current element. Don't directly alter this stack,
as doing so causes an invalid state for the SAX parser; you should use it as read-only information.
Now you can recompile the classes and run the new program. You will see the same output as Listing 2's example, with much less work and more readable source code.
Because a computer can discover an XML file's structure by parsing the XML Schema, a Generator class can go a long way to helping create a SAX parser's structure. In this article, you learned how to create an easy-to-use
skeleton SAX parser with a SAX code generator, and also saw how to use this parser to parse XML files. The code generator
saves you hours of SAX parser development time, and its structure provides you with more readable and maintainable source
code.
You have also received a set of source code templates that you can modify to meet your specific needs. With these templates, you can create any SAX structure. Of course, you can also apply these templates to problems other than SAX—I'd like to hear about any new and interesting ways in which you use the code generator.
Read more about Enterprise Java in JavaWorld's Enterprise Java section.