Search code examples
javaandroidxmlparsingsax

SAX parser ignores text because of a <br /> tag


have a slight problem here and I don't know how to fix it. I have an XML file that looks like this:

<?xml version="1.0"?>
<item>
 <title>Item 1</name>
 <description>Description Text 1&lt;br /&gt;Description Text 2</description>
</item>

And I have a SAX parser that looks like this:

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    if ("item".equals(qName)) {
        currentItem = new Item();
    } else if ("title".equals(qName)) {
        parsingTitle = true;
    } else if ("description".equals(qName)) {
        parsingDescription = true;
    }
}

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

    System.out.println("Testing endelement");

    if ("item".equals(qName)) {
        Items.add(currentItem);
        currentItem = null;
    } else if ("title".equals(qName)) {
        parsingTitle = false;
    } else if ("description".equals(qName)) {
        parsingDescription = false;
    }
}

@Override
public void characters(char[] ch, int start, int length) throws SAXException {

    System.out.println("writing");

    if (parsingTitle) {
        if (currentItem != null)
            currentItem.setTitle(new String(ch, start, length));
    } else if (parsingDescription) {
        if (currentItem != null) {
            currentItem.setDescription(new String(ch, start, length));
            parsingDescription = false;
        }
    }

The problem is that SAX is parsing only the first part of the text in the tag, up until the "<br />" text (which is the
tag) and ignores the rest. How do I make the SAX parser ignore "<br />" and parse the rest of the description?

Thanks.


Solution

  • As mentioned in the comments, you can't rely on characters() to provide all of an element's text in one shot. I recommend something like this (look for the comments in the code to see where I modified it) and then making a similar modification for the title:

    // buffer to hold description
    private StringBuffer descriptionBuffer;
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if ("item".equals(qName)) {
            currentItem = new Item();
        } else if ("title".equals(qName)) {
            parsingTitle = true;
        } else if ("description".equals(qName)) {
            parsingDescription = true;
            // initialize buffer
            descriptionBuffer = new StringBuffer();
        }
    }
    
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
    
        System.out.println("Testing endelement");
    
        if ("item".equals(qName)) {
            Items.add(currentItem);
            currentItem = null;
        } else if ("title".equals(qName)) {
            parsingTitle = false;
        } else if ("description".equals(qName)) {
            // Put contents of buffer into description
            currentItem.setDescription(descriptionBuffer.toString());
            descriptionBuffer = null;
            parsingDescription = false;
        }
    }
    
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
    
        System.out.println("writing");
    
        if (parsingTitle) {
            if (currentItem != null)
                currentItem.setTitle(new String(ch, start, length));
        } else if (parsingDescription) {
            // add to buffer
            descriptionBuffer.append(ch, start, length); 
        }
    }