Search code examples
androidsaxparserduplication

Android SAXParser Leftovers


I have an Android app that parses XML using SAXParser. Everything goes ok, excepting some texts that get duplicated and trimmed. For example: "Just do it, even if you do not know how!" becomes " not know how!"

This is the DefaultHandler code. 10x!

DefaultHandler handler = new DefaultHandler()
    {
        Praise praise;
        String elementValue = null;
        Boolean elementOn = false;

        @Override
        public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException
        {

            if (localName.equals("praise"))
            {
                praise = new Praise();
                elementOn = true;
            }
        }

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

            // elementOn = false;

            if (localName.equals("PRAISE_TEXT"))
            {
                praise.setPraiseText(elementValue);
            }
            if (localName.equals("MOOD"))
            {
                praise.setMood(elementValue);
            }
            if (localName.equals("RATING"))
            {
                praise.setRating(Integer.valueOf(elementValue));
            }
            if (localName.equals("praise"))
            {
                elementOn = false;
                if (update)
                {
                    if (database.getPraiseByText(praise.getPraiseText(), db) == null)
                    {
                        database.addPraise(db, praise.getPraiseText(), praise.getMood(),
                            Integer.valueOf(praise.getRating()));
                    }
                }
                else
                    database.addPraise(db, praise.getPraiseText(), praise.getMood(),
                        Integer.valueOf(praise.getRating()));
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException
        {
            // StringBuffer b = new StringBuffer();
            if (elementOn)
            {
                elementValue = new String(ch, start, length);}}};

Solution

  • In SaxParsing, you do not have guarantee that characters will be called only once!

    For this, you should concatenate all the characters you receive withing the same element

    This is a just your code with a small modification. You should use StringBuilder instead of using String (:

    DefaultHandler handler = new DefaultHandler()
        {
            Praise praise;
            String elementValue = null;
            Boolean elementOn = false;
    
            @Override
            public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException
            {
                elementValue = new String();
    
                if (localName.equals("praise"))
                {
                    praise = new Praise();
                    elementOn = true;
                }
            }
    
            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException
            {
                if (localName.equals("PRAISE_TEXT"))
                {
                    praise.setPraiseText(elementValue);
                }
                if (localName.equals("MOOD"))
                {
                    praise.setMood(elementValue);
                }
                if (localName.equals("RATING"))
                {
                    praise.setRating(Integer.valueOf(elementValue));
                }
                if (localName.equals("praise"))
                {
                    elementOn = false;
                    if (update)
                    {
                        if (database.getPraiseByText(praise.getPraiseText(), db) == null)
                        {
                            database.addPraise(db, praise.getPraiseText(), praise.getMood(),
                                Integer.valueOf(praise.getRating()));
                        }
                    }
                    else
                        database.addPraise(db, praise.getPraiseText(), praise.getMood(),
                            Integer.valueOf(praise.getRating()));
                }
            }
    
            @Override
            public void characters(char[] ch, int start, int length) throws SAXException
            {
                // StringBuffer b = new StringBuffer();
                if (elementOn)
                {
                    elementValue = elementValue + new String(ch, start, length);
                }
            }
        };