import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;

public class AveragePrice extends DefaultHandler {

  private int count = 0;
  private boolean isFiction = false;
  private double totalPrice = 0.0;
  private StringBuffer content = new StringBuffer();

  public AveragePrice () {super();}

  public void determineAveragePrice() throws Exception 
  {
    XMLReader xr = new org.apache.xerces.parsers.SAXParser();
    AveragePrice handler = new AveragePrice();
    xr.setContentHandler(handler);
    xr.parse("books.xml");
  }         

  public void startElement(String uri, String localName, String rawName, Attributes atts) throws SAXException 
  {
    if (localName.equals("book")) 
    {
      String category = atts.getValue("category");
      isFiction = (category!=null && category.equals("fiction"));
      if (isFiction) count++;
    }
    content.setLength(0);
  }

  public void characters(char[] chars, int start, int len) throws SAXException 
  {
    content.append(chars, start, len);
  }

  public void endElement(String uri, String localName, String rawName) throws SAXException 
  {
    if (localName.equals("price") && isFiction) 
    {
      try 
      { 
        double price = new Double(content.toString()).doubleValue();
        totalPrice += price;
      }
      catch (java.lang.NumberFormatException err) 
      {
        throw new SAXException("Price is not numeric");
      }
    }
    content.setLength(0);
  }

  public void endDocument() throws SAXException 
  {
      if (count > 0) {
	  System.out.println("The average price of fiction books is " + totalPrice / count);
      } 
      else {
	  System.out.println("No fiction books found.");
      }
  }

  public static void main (String args[]) throws java.lang.Exception 
  {
    try 
    {
      (new AveragePrice()).determineAveragePrice();
    }
    catch (SAXException err) 
    {
      System.err.println("Parsing failed: " + err.getMessage());
    }
  }
}
