TheKolaNN
TheKolaNN

Reputation: 989

Java SAX is not parsing properly

I would appreciate any help on this. This is my first handler I wrote.

I got I REST Webservice returning XML of links. It has quite simple structure and is not deep. I wrote a handler for this:

public class SAXHandlerLnk extends DefaultHandler {

    public List<Link> lnkList = new ArrayList();
    Link lnk = null;
    private StringBuilder content = new StringBuilder();

    @Override
    //Triggered when the start of tag is found.
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (qName.equals("link")) {
            lnk = new Link();
        }
    }
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equals("link")) {
            lnkList.add(lnk);
        }
        else if (qName.equals("applicationCode")) {
            lnk.applicationCode = content.toString();
        }
        else if (qName.equals("moduleCode")) {
            lnk.moduleCode = content.toString();
        }
        else if (qName.equals("linkCode")) {
            lnk.linkCode = content.toString();
        }
        else if (qName.equals("languageCode")) {
            lnk.languageCode = content.toString();
        }
        else if (qName.equals("value")) {
            lnk.value = content.toString();
        }
        else if (qName.equals("illustrationUrl")) {
            lnk.illustrationUrl = content.toString();
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        content.append(ch, start, length);
    }
}

Some XML returned can be empty eg. or . When this happens my handler unfortunatelly adds previous value to the Object lnk. So when is empty in XML, I got lnk.illustrationUrl = content; equal to lnk.value.

Link{applicationCode='onedownload', moduleCode='onedownload',...}

In the above example, I would like moduleCode to be empty or null, because in XML it is an empty tag.

Here is the calling class:

public class XMLRepositoryRestLinksFilterSAXParser {

    public static void main(String[] args) throws Exception {
        SAXParserFactory parserFactor = SAXParserFactory.newInstance();
        SAXParser parser = parserFactor.newSAXParser();
        SAXHandlerLnk handler = new SAXHandlerLnk();
        parser.parse({URL}, handler);

        for ( Link lnk : handler.lnkList){
            System.out.println(lnk);
        }
    }
}

Upvotes: 2

Views: 366

Answers (1)

predi
predi

Reputation: 5928

Like stated in my comment, you'd do the following. The callbacks are usually called in startElement, characters, (nested?), characters, endElement order, where (nested?) represents an optional repeat of the entire sequence.

@Override
//Triggered when the start of tag is found.
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    content = null;
    if (qName.equals("link")) {
        lnk = new Link();
    }        
}

Note that characters may be called multiple times per a single XML element in your document, so your current code might fail to capture all content. You'd be better off using a StringBuilder instead of a String object to hold your character content and append to it. See this answer for an example.

Upvotes: 3

Related Questions