0

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.

  • What SAX parser are you using? – JLRishe Apr 05 '14 at 16:11
  • Android java sax parser, if I understand the question correctly. – user3078436 Apr 05 '14 at 16:17
  • If you remove the `parsingDescription = false` from your `characters` handler and change `currentItem.setDescription(new String(ch, start, length));` to `currentItem.setDescription(currentItem.getDescription() + new String(ch, start, length));`, does the result change at all? – JLRishe Apr 05 '14 at 16:25
  • 1
    Possible duplicate of http://stackoverflow.com/questions/13723855/android-sax-parser-incomplete-char-array – JLRishe Apr 05 '14 at 16:30
  • Unfortunately, the code gave doesn't help (Changes the parsed description to "nullDescription Text 1") and I don't quite understand how the link you provided is related to my issue. – user3078436 Apr 05 '14 at 17:15
  • From the looks of it, the link I provided seems very much related to your issue, because the accepted answer points out that you can't rely on all of an element's text content to come through in a single call to `characters()` (your code above stops adding text to description after a single call to `characters()`). I can see why that `null` value appeared there and that would need to be accounted for, but are you saying that you removed `parsingDescription = false` from your `characters` handler and still didn't get the rest of the text? – JLRishe Apr 05 '14 at 20:06
  • I am so sorry, you were right all along. That "parsingDescription = false" was the the reason why this problem was occurring. Why did I even put that code in the first place? Thanks a lot! – user3078436 Apr 05 '14 at 22:07
  • Oh, and since you mentioned that you can see why the null value appeared, could you please explain why this is happening and how it can be fixed? – user3078436 Apr 05 '14 at 23:02
  • It's happening because description is `null` the first time `getDescription()` is called in `characters` and that gets concatenated with the first portion of the description. See my answer to see how to improve this. – JLRishe Apr 06 '14 at 05:43

1 Answers1

1

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); 
    }
}
JLRishe
  • 99,490
  • 19
  • 131
  • 169