BlackBerry/J2ME - SAX parse collection of objects with attributes

后端 未结 2 1701
别那么骄傲
别那么骄傲 2020-12-21 21:00

I have a problem with using the SAX parser to parse a XML file. It is a complex XML file, it is like the following.

    
        

        
                      
相关标签:
2条回答
  • 2020-12-21 21:48
    package com.ahoy.utils;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.util.Vector;
    import net.rim.device.api.xml.parsers.ParserConfigurationException;
    import net.rim.device.api.xml.parsers.SAXParser;
    import net.rim.device.api.xml.parsers.SAXParserFactory;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    import com.ahoy.bean.DealData;
    
    public class XMLDealsParser extends DefaultHandler  {
    
        boolean currentElement = false;
        String currentValue = null;
        DealData currentDealData = null;
        String previousNodeName = new String("nil");
        public Vector dealVector = new Vector(5);
        //public static Vector geoDataItems = null;
        public XMLDealsParser(String data){
            InputStream inputStream=null;
            SAXParser sp;
            try {
                inputStream = new ByteArrayInputStream(data.getBytes());
                SAXParserFactory spf = SAXParserFactory.newInstance();
    
                sp = spf.newSAXParser();
    
                sp.parse(inputStream, this);
            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                Logger.error(" -------XMLDealsParser  >> XMLDealsParser() ",e);
    
                e.printStackTrace();
            } catch (SAXException e) {
                // TODO Auto-generated catch block
                Logger.error(" -------XMLDealsParser  >> XMLDealsParser() ",e);
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                Logger.error(" -------XMLDealsParser  >> XMLDealsParser() ",e);
                e.printStackTrace();
            }
        }
    
        public Vector getDealList() {
            return dealVector;
        }
    
        public void setDealList(Vector dealList) {
            this.dealVector = dealList;
        }
    
        /** Called when tag starts ( ex:- <name>AndroidPeople</name> 
         * -- <name> )*/
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
    
            currentElement = true;
    
            if (localName.equals("deal"))
            {
                /** Start */ 
                this.currentDealData = new DealData();
    
            }if (localName.equals("id"))
            {
                /** Start */
            }
        }
    
        /** Called when tag closing ( ex:- <name>AndroidPeople</name> 
         * -- </name> )*/
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
    
            currentElement = true;
    
            /** set value */ 
            if (localName.equalsIgnoreCase("deal"))
            {
                dealVector.addElement(currentDealData);
                return;
            }
            if (localName.equalsIgnoreCase("id"))
            {
                currentDealData.id = currentValue;
            }else if (localName.equalsIgnoreCase("score"))
            {
                currentDealData.score = currentValue;
            }else if (localName.equalsIgnoreCase("shortDescription"))
            {
                currentDealData.shortDescription = currentValue;
            }
            //dealVector.addElement(currentGeoData);
            System.out.println("dealVector.size():"+ dealVector.size());
        }
    
        /** Called to get tag characters ( ex:- <name>AndroidPeople</name> 
         * -- to get AndroidPeople Character ) */
        public void characters(char[] ch, int start, int length)
                throws SAXException {
    
            if (currentElement) {
                currentValue = new String(ch, start, length);
                System.out.println("DATA: " + currentValue);
                currentElement = false;
            }
        }
    
        public void callback(String data) throws Exception {
            // TODO Auto-generated method stub
    
        }
    }
    
    0 讨论(0)
  • 2020-12-21 22:04

    UPDATE updated to skip span and concat values from fields with same name

    Hi! I would suggest to use hashtable to handle those "fields":

    class XMLObject {
        private Hashtable mFields = new Hashtable();
        private int mN = -1;
    
        public int getN() {
            return mN;
        }
    
        public void setN(int n) {
            mN = n;
        }
    
        public boolean isFieldExist(String key)
        {
            return mFields.containsKey(key);
        }
    
        public String getStringField(String key) {
            return (String) mFields.get(key);
        }
    
        public void setStringField(String key, String value) {
            mFields.put(key, value);
        }
    
        public String getPID() {
            return getStringField("PID");
        }
    
        public void setPID(String pid) {
            setStringField("PID", pid);
        }
    
        public String getDcCoverage() {
            return getStringField("dc.coverage");
        }
    
        public void setDcCoverage(String dcCoverage) {
            setStringField("dc.coverage", dcCoverage);
        }
    
        public String getFgsOwnerId() {
            return getStringField("fgs.ownerId");
        }
    
        public void setFgsOwnerId(String fgsOwnerId) {
            setStringField("fgs.ownerId", fgsOwnerId);
        }
    
        public String dccreator() {
            return getStringField("dc.creator");
        }
    
        public void dccreator(String dccreator) {
            setStringField("dc.creator", dccreator);
        }
    
        public String getdcformat() {
            return getStringField("dc.format");
        }
    
        public void setdcformat(String dcformat) {
            setStringField("dc.format", dcformat);
        }
    
        public String getdcidentifier() {
            return getStringField("dc.identifier");
        }
    
        public void setdcidentifier(String dcidentifier) {
            setStringField("dc.identifier", dcidentifier);
        }
    
        public String getdclanguage() {
            return getStringField("dc.language");
        }
    
        public void setdclanguage(String dclanguage) {
            setStringField("dc.language", dclanguage);
        }
    
        public String getdcpublisher() {
            return getStringField("dc.publisher");
        }
    
        public void setdcpublisher(String dcpublisher) {
            setStringField("dc.publisher", dcpublisher);
        }
    
        public String getdcsubject() {
            return getStringField("dc.subject");
        }
    
        public void setdcsubject(String dcsubject) {
            setStringField("dc.subject", dcsubject);
        }
    
        public String getdctitle() {
            return getStringField("dc.title");
        }
    
        public void setdctitle(String dctitle) {
            setStringField("dc.title", dctitle);
        }
    
        public String getdctype() {
            return getStringField("dc.type");
        }
    
        public void setdctype(String dctype) {
            setStringField("dc.type", dctype);
        }
    
        public String toString() {
            StringBuffer sb = new StringBuffer();
            sb.append("N:" + mN + ";");
            Enumeration keys = mFields.keys();
            while (keys.hasMoreElements()) {
                String key = (String) keys.nextElement();
                sb.append(key + ":" + mFields.get(key) + ";\n");
            }
            return sb.toString();
        }
    }
    

    Then in handler you will not have to set some specific class member, just put value using "name" attribute as a key:

    class XMLObjectHandler extends DefaultHandler {
        private String mCurrentTag = "";
        private String mCurrentText = "";
        private Attributes mCurrentAttr = null;
        private XMLObject[] mXMLObjects = new XMLObject[] {};
        private XMLObject mCurrentXMLObject = new XMLObject();
        private boolean mIgnoreTag = false;
    
        public XMLObject[] getXMLObjects() {
            return mXMLObjects;
        }
    
        public void startElement(String uri, String localName, String name,
                Attributes attributes) throws SAXException {
            mIgnoreTag = mCurrentTag.equalsIgnoreCase("field")
                    && name.equalsIgnoreCase("span");
    
            if (!mIgnoreTag) {
                mCurrentTag = name;
                mCurrentAttr = attributes;
            } else {
                mCurrentText += " ";
            }
            if (mCurrentTag.equalsIgnoreCase("object")) {
                mCurrentXMLObject = new XMLObject();
                mCurrentXMLObject.setN(Integer
                        .parseInt(mCurrentAttr.getValue("no")));
            }
        }
    
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            if (mCurrentTag.equalsIgnoreCase("field"))
                mCurrentText = mCurrentText.concat(new String(ch, start, length));
        }
    
        public void endElement(String uri, String localName, String name)
                throws SAXException {
            if (name.equalsIgnoreCase("field")) {
                String fieldName = mCurrentAttr.getValue("name");
                if(mCurrentXMLObject.isFieldExist(fieldName))
                {
                    mCurrentText = mCurrentXMLObject.getStringField(fieldName) 
                                    + " " + mCurrentText;
                }           
                mCurrentXMLObject.setStringField(fieldName, mCurrentText);
            } else if (name.equalsIgnoreCase("object")) {
                Arrays.add(mXMLObjects, mCurrentXMLObject);
            }
            if (!mIgnoreTag) {
                mCurrentTag = "";
                mCurrentText = "";
            } else {
                mCurrentText += " ";
            }
        }
    }
    

    See sample usage:

        public Scr() {
            StringBuffer sb = new StringBuffer();
            sb.append("<Objects>");
            sb.append("<Object no=\"1\">");
            sb
                    .append("<field name=\"PID\">ilives:87877</field>"+
                "<field name=\"dc.coverage\">Charlottetown</field>"+
                "<field name=\"fgs.ownerId\">fedoraAdmin</field>");
            sb.append("</Object>");
            sb.append("<Object no=\"2\">");
            sb
                    .append("<field name=\"PID\">ilives:87878</field>"+
                "<field name=\"dc.coverage\">Rimston</field>"+
                "<field name=\"fgs.ownerId\">jamesAdmin</field>");
            sb.append("</Object>");
            sb.append("</Objects>");
    
            String xml = sb.toString();
            ByteArrayInputStream bais = 
                new ByteArrayInputStream(xml.getBytes());       
            XMLObject[] xmlObjects = getXMLObjects(bais);
            for (int i = 0; i < xmlObjects.length; i++) {
                XMLObject o = xmlObjects[i];
                add(new LabelField(o.toString()));
            }
        }
    
        static XMLObject[] getXMLObjects(InputStream is) {
            XMLObjectHandler xmlObjectHandler = new XMLObjectHandler();
                try {
                    SAXParser parser = SAXParserFactory.newInstance()
                            .newSAXParser();
                    parser.parse(is, xmlObjectHandler);
                } catch (ParserConfigurationException e) {
                    e.printStackTrace();
                } catch (SAXException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return xmlObjectHandler.getXMLObjects();
        }
    }
    

    alt text http://img441.imageshack.us/img441/1372/saxj.jpg

    PS If there will be performance issues (say having over 1000 xml objects) just replace hashtable with class members and update handler accordingly...

    0 讨论(0)
提交回复
热议问题