2

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);
        }
    }
}
2
  • 1
    Assuming that your XML does not contain mixed content, simply clear your content variable on each startElement() callback. Commented Aug 22, 2014 at 8:40
  • that was trivial :). THANKS! Commented Aug 22, 2014 at 9:01

1 Answer 1

3

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.

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

1 Comment

thank you for a hint with StringBuilder too, I already edited the code above to improve it

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.