0

I am having trouble with the SAX Parser where it is not retrieving the full xml document. I can see that it originates from the list as only 1 entry is added to the list when there should really be 3 entries.

Can anyone solve the issue by allowing all three entries to be display? Thank You.

catalogue.xml

<?xml version="1.0" ?>
<CATALOG>
  <BOOK>

    <TITLE>A Certain Justice</TITLE>
    <AUTHOR>P.D. James</AUTHOR>
    <YEAR-PUBLISHED>1998</YEAR-PUBLISHED>
    <ISBN>0375401091</ISBN>

  </BOOK>
  <BOOK>

    <TITLE>Ashworth Hall</TITLE>
    <AUTHOR>Anne Perry</AUTHOR>
    <YEAR-PUBLISHED>1997</YEAR-PUBLISHED>
    <ISBN>0449908445</ISBN>

  </BOOK>
  <BOOK>

    <TITLE>L.A. Confidential</TITLE>
    <AUTHOR>James Ellroy</AUTHOR>
    <YEAR-PUBLISHED>1997</YEAR-PUBLISHED>
    <ISBN>0446674249</ISBN>

  </BOOK>
  <BOOK>

    <TITLE>Shadow Woman</TITLE>
    <AUTHOR>Thomas Perry</AUTHOR>
    <YEAR-PUBLISHED>1997</YEAR-PUBLISHED>
    <ISBN>0679453024</ISBN>

  </BOOK>

</CATALOG>

Catalogue.java

package londonmet.cs.xml;

public class Catalogue {

  public String title;
  public String author;
  public String yearPublished;
  public String isbn;

  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  public String getAuthor() {
    return author;
  }
  public void setAuthor(String author) {
    this.author = author;
  }
  public String getYearPublished() {
    return yearPublished;
  }
  public void setYearPublished(String yearPublished) {
    this.yearPublished = yearPublished;
  }
  public String getIsbn() {
    return isbn;
  }
  public void setIsbn(String isbn) {
    this.isbn = isbn;
  }

  @
  Override
  public String toString() {
    return "Catalogue::  Title=" + this.title + " Author=" + this.author + " Year Published=" + this.yearPublished +
      " ISBN=" + this.isbn;
  }





}

SAXParserExample.java

package londonmet.cs.xml;



import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class SAXParserExample extends DefaultHandler {

  List < Catalogue > myCata;

  private String tempVal;

  //to maintain context
  private Catalogue tempEmp;


  public SAXParserExample() {
    myCata = new ArrayList < Catalogue > ();
  }

  public void runExample() {
    parseDocument();
    printData();
  }

  private void parseDocument() {

    //get a factory
    SAXParserFactory spf = SAXParserFactory.newInstance();
    try {

      //get a new instance of parser
      SAXParser sp = spf.newSAXParser();

      //parse the file and also register this class for call backs
      sp.parse("catalogue.xml", this);

    } catch (SAXException se) {
      se.printStackTrace();
    } catch (ParserConfigurationException pce) {
      pce.printStackTrace();
    } catch (IOException ie) {
      ie.printStackTrace();
    }
  }

  /**
   * Iterate through the list and print
   * the contents
   */
  private void printData() {

    System.out.println("No of Books '" + myCata.size() + "'.");

    Iterator < Catalogue > it = myCata.iterator();
    while (it.hasNext()) {
      System.out.println(it.next().toString());
    }
  }


  //Event Handlers
  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    //reset
    tempVal = "";
    if (qName.equalsIgnoreCase("Catalog")) {
      //create a new instance of employee
      tempEmp = new Catalogue();

    }
  }


  public void characters(char[] ch, int start, int length) throws SAXException {
    tempVal = new String(ch, start, length);
  }

  public void endElement(String uri, String localName, String qName) throws SAXException {

    if (qName.equalsIgnoreCase("Catalog")) {
      //add it to the list
      myCata.add(tempEmp);

    } else if (qName.equalsIgnoreCase("TITLE")) {
      tempEmp.setTitle(tempVal);
    } else if (qName.equalsIgnoreCase("AUTHOR")) {
      tempEmp.setAuthor(tempVal);
    } else if (qName.equalsIgnoreCase("YEAR-PUBLISHED")) {
      tempEmp.setYearPublished(tempVal);
    } else if (qName.equalsIgnoreCase("ISBN")) {
      tempEmp.setIsbn(tempVal);
    }

  }

  public static void main(String[] args) {
    SAXParserExample spe = new SAXParserExample();
    spe.runExample();
  }

}

1 Answer 1

3

You want to collect information about every BOOK element in your XML document.

Therefore in startElement and endElement you should watch for the start and end of BOOK and not CATALOG elements:

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
    // reset
    tempVal = "";
    if (qName.equalsIgnoreCase("BOOK")) // not CATALOG
        ...
}


public void endElement(String uri, String localName, String qName) throws SAXException
{
    if (qName.equalsIgnoreCase("BOOK"))  // not CATALOG
    {
        // add it to the list
        myCata.add(tempEmp);
    }
    ...

Consequently you should rename your Catalogue class to Book class since it represents a single book and not a catalogue (= collection of books).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.