Link to home
Start Free TrialLog in
Avatar of no158
no158

asked on

XML startElement with collection

How would I implement a collection within this function or a different one to collect the title of the feed, its pubDate, and its url?

Main goal here is to have a collection of objects that contains the 3 types of info (title of the feed, its pubDate, and its url) to be able to sort the info by its date so when the data is displayed the information is organized. Not sure if the collection should gather the data here but he seems like the logical place to get the data.

  // This gets called when the parser reaches an element
  public void startElement(String uri, String localName, String qName, Attributes atts) {
            int length = atts.getLength();
   
            for (int i=0; i<length; i++) {
              if(){
              String name = atts.getQName(i);
              String value = atts.getValue(i);

              }
              //System.out.println("Starting : " + qName);
              //if(qName == "pubDate")
              //this.qName = qName;
            }
  }
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

SAX is not convenient for what seems like the hierarchical view you need. Unless prevented by memory requirements, i would use XPath or better still commons Digester
Avatar of no158
no158

ASKER

I'm not fimilar with XPath or Digester, tried using Digester the other day and the package needed for it is not installed properly and I'd much rather avoid it. I've never heard of XPath till now, how would that make this task easier?
I'd use Digester. Just install Digester. Get the binary. Extract the jar and make sure it's in your compile time and runtime classpaths
you need to check what element it is and base your action on that.
for example if it is the start of a new item for your list then create a new instance (and store a reference to it in your handler) and add it to your list
if it is an attribute of the item then call the relevent setter on the current item.
Avatar of no158

ASKER

What collection would work best for storing an object, which is holding three data types? What would the code look like to creat the object holding the three types?
Avatar of no158

ASKER

I think my main problem here is not being able to visualize how the data is being stored and can't really see how to set up the rest.
something like:

public MyHandler ....
{
   private List myList = new ArrayList();
   private ByBean current = null;

   public void startElement(...
   {
        if (element is myBean)
        {
             current = new MyBean();
             myList.add(current);
        }
        else if (element is myBean's name)
        {
            current.setName(value);
        }
        else if......
You use a collection of type X where X is the object which holds the three data types. Digester will do this for you automatically after you define the mapping. XMLBeans would too
>> What collection would work best for storing an object, which is holding three data types?

You would create a class for holding those 3 data-types within and use any kind of Collection to hold objects of that class, e.g. a list implementation like ArrayList. If you need to search for elements, go for a Map like HashMap.
Isn't that what i just said ;-)
Not entirely. I think you were referring to automatically converting the XML to objects and I don't see HashMaps being mentioned anywhere :)
Avatar of no158

ASKER

  public void startElement(String uri, String localName, String qName, Attributes atts) {
   
    if(qName == "title") {
      System.out.println(atts.getValue(qName));
      //myList.add(atts.getValue(qName));
    }
    //System.out.println("Starting : " + qName);
    //this.qName = qName;
  }

atts.getValue(qName) is not giving me the info i'm looking for, its giving me a null value....what seems to be wrong here
if("title".equals(qName))
>> atts.getValue(qName) is not giving me the info i'm looking for, its giving me a null value....

Make sure the characters are in the correct case.
If you stick to SAX you'll have to maintain your own stacks, which i'm afraid will entail reinventing the wheel
Avatar of no158

ASKER

The IF statement is picking up the tags because it displayed null for each title tag there was in the xml file. Must be with atts.getValue(qName) but that looks correct.
Why would the attribute have the same name ('title')?
>> The IF statement is picking up the tags because it displayed null for each title tag there was in the xml file.

But nevertheless, that comparision is incorrect - you should use equals (). If you use ==, it means you are comparing the references and they could be different, though pointing to string objects having the same set of characters.
Avatar of no158

ASKER

http://java.sun.com/j2se/1.5.0/docs/api/org/xml/sax/Attributes.html

The getValue(String qName) method wants it, I'm thinking it should display the contents of the tag. What else would it display?
>>I'm thinking it should display the contents of the tag. What else would it display?

No, it wouldn't. It displays a named attribute
I would think the case of "title" is incorrect - did you try getValue ( 0 ), getValue ( 1 ) to see if it is printing the correct values of some attributes?
Avatar of no158

ASKER

I've tried a few different ways to access this method but it seems as if the parser is entering in the correct information, since i can't seem to get the int start and int lenth correct. Any ideas?

  public void characters(char[] ch, int start, int length) {
    String data = new String(ch, start, length).trim();
    if (data.length() > 0) {
      //System.out.println(data);
    }
  }
Avatar of no158

ASKER

int's don't seem to be working in getValue() same result
>>since i can't seem to get the int start and int lenth correct.

What do you mean by that?
Avatar of no158

ASKER

Well I wanted to use that method because that method is displaying the correct contents of the tag, the parser can use it...so i thought why can't I, problem is that I don't have an easy way of feeding it the correct position on the fly. If I were able to get the position after the tag I'd be able to get the information.
>>If I were able to get the position after the tag I'd be able to get the information.

I've already outlined the difficulties above - you seem to be ignoring my comments ;-)
Avatar of no158

ASKER

I understand you dislike using SAX because it is old news I atually agree with you but as it stands I need to get this done without any packages. I need to use either SAX or DOM because they don't require any extra packages.
>>I understand you dislike using SAX because it is old news

No - there's no problem with SAX and by no means is it old news. It's just not appropriate. Go for XPath then
Avatar of no158

ASKER

I'm not sure how to use xpath, i'm using http://javaalmanac.com/egs/org.w3c.dom/xpath_GetElemById.html?l=rel as an example. I don't see how to access the document its just variable with xpath in it.

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;  
import javax.xml.parsers.FactoryConfigurationError;  
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
import java.io.File;
import java.io.IOException;

public class RssReader {
  static Document document;
 
  public static void main(String[] args) {
       
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
     
      DocumentBuilder builder = factory.newDocumentBuilder();
      document = builder.parse( new File(args[0]) );
      document = builder.newDocument();
     
    } catch (Exception e) {

      e.printStackTrace(System.err);
    }
  }
}
xpath does not appear to be appropriate
use sax and build up your colleaction of beans as you read thru the xml  as i outlined above
Avatar of no158

ASKER

Problem with that is the IF statements are not working correctly, unless I'm missing the point of the outline. I'm getting null values as my return. So I can't even get to creating a collection yet.

  public void startElement(String uri, String localName, String qName, Attributes atts) {
   
    if("title".equals(qName)) {
      System.out.println(atts.getValue(qName));
      //list.add(atts.getValue(qName));
    }
   if("pubDate".equals(qName)) {
      System.out.println(atts.getValue(qName));
    }
    if("link".equals(qName)) {
      System.out.println(atts.getValue(qName));
    }
    //System.out.println("Starting : " + qName);
  }
>>xpath does not appear to be appropriate

Why not?

no158, please post an example of your xml and what you want from it and i'll show you how to code it?
Avatar of no158

ASKER

http://www.rssboard.org/files/sample-rss-2.xml

My main goal is to get a collection of three types Title of the item, pubDate, and the URL link. The collection is going to be displayed sorted by the date.

Tue, 20 May 2003 08:56:02 GMT  Astronauts' Dirty Laundry  http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp
Tue, 27 May 2003 08:37:32 GMT  The Engine That Does More  http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp
Tue, 03 Jun 2003 09:39:21 GMT  Star City  http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp
Tue, 10 Jun 2003 04:00:00 GMT  Liftoff News  http://liftoff.msfc.nasa.gov/

The tricky part that I have not figured out yet is how to format the date so it can be sortable.

>>The tricky part that I have not figured out yet is how to format the date so it can be sortable.

You store them as Date. That's sortable
You'll need to write a custom comparator this way:

http://java.sun.com/docs/books/tutorial/collections/interfaces/order.html 
Avatar of no158

ASKER

How exactly do you start off by using xpath?
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial