2012-04-24 56 views
0

Iam使用sax解析器解析3.8 mb的xml文件。它在解析時的加載時間大約爲3.5分鐘。如何在android中使用saxparser從URL中解析大型xml文件(3.8 mb)?

public class sentmsghandler extends DefaultHandler { 
public folder folderobj; 
public Contact contact; 
public Parent parent; 
public Student student; 
private StringBuilder builder; 
Boolean repeat; 

public folder getfolder() { 
    return folderobj; 
} 

@Override 
public void endElement(String uri, String localName, String qName) 
     throws SAXException { 
    // TODO Auto-generated method stub 
    super.endElement(uri, localName, qName); 
    // Log.i("testing parent contact",localName); 
    if (this.folderobj != null) { 

     String st = builder.toString(); 
     if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.SchoolName.toUpperCase())) { 
      folderobj.setSchoolName(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.ParentCode.toUpperCase())) { 
      parent.setParentCode(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.FamilyCode.toUpperCase())) { 
      if (!repeat) { 
       parent.setFamilyCode(st); 
      } else { 
       student.setFamilyCode(st); 
      } 
     } 

     else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.FamilyName.toUpperCase())) { 

      if (!repeat) { 
       parent.setFamilyName(st); 
      } else { 
       student.setFamilyName(st); 
      } 
     } 

     else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.GivenNames.toUpperCase())) { 

      if (!repeat) { 
       parent.setGivenNames(st); 
      } else { 
       student.setGivenNames(st); 
      } 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.ParentType.toUpperCase())) { 
      parent.setParentType(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.EmailAddress.toUpperCase())) { 
      parent.setEmailAddress(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.MobilePhone.toUpperCase())) { 
      parent.setMobilePhone(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.LandLineNumber.toUpperCase())) { 
      parent.setLandLineNumber(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.Primary.toUpperCase())) { 
      parent.setPrimary(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.StudentCode.toUpperCase())) { 
      student.setStudentCode(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.SchoolYearLevel.toUpperCase())) { 
      student.setSchoolYearLevel(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.RollClass.toUpperCase())) { 
      student.setRollClass(st); 
     } else if (localName.toUpperCase().equalsIgnoreCase(
       BaseFeedParser.House.toUpperCase())) { 
      student.setHouse(st); 
     } 

    } 
    builder.setLength(0); 
} 

@Override 
public void startElement(String uri, String localName, String qName, 
     Attributes attributes) throws SAXException { 
    // TODO Auto-generated method stub 
    super.startElement(uri, localName, qName, attributes); 

    if (localName.toUpperCase().equalsIgnoreCase(
      BaseFeedParser.Folder.toUpperCase())) { 
     folderobj = new folder(); 
    } 

    else if (localName.toUpperCase().equalsIgnoreCase(
      BaseFeedParser.Contact.toUpperCase())) { 
     contact = new Contact(); 
     folderobj.getContact_list().add(contact); 
    } else if (localName.toUpperCase().equalsIgnoreCase(
      BaseFeedParser.Parent.toUpperCase())) { 
     parent = new Parent(); 
     repeat = false; 
     contact.getParent_list().add(parent); 
    } else if (localName.toUpperCase().equalsIgnoreCase(
      BaseFeedParser.Student.toUpperCase())) { 
     student = new Student(); 
     repeat = true; 
     parent.getStudent_list().add(student); 
    } 

} 

@Override 
public void characters(char[] ch, int start, int length) 
     throws SAXException { 
    // TODO Auto-generated method stub 
    super.characters(ch, start, length); 
    builder.append(ch, start, length); 
} 

@Override 
public void startDocument() throws SAXException { 
    // TODO Auto-generated method stub 
    super.startDocument(); 
    folderobj = new folder(); 
    builder = new StringBuilder(); 
    repeat = false; 
} 

}

Saxfeedparser.java

import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

public class SaxFeedParser extends BaseFeedParser { 

    public SaxFeedParser(String feedUrl) { 
     super(feedUrl); 
     // TODO Auto-generated constructor stub 
    } 

    public folder parse() throws RuntimeException { 
     SAXParserFactory factory = SAXParserFactory.newInstance(); 
     sentmsghandler handler = null; 
     try { 
      SAXParser parser = factory.newSAXParser(); 
      handler = new sentmsghandler(); 
      parser.parse(this.getInputStream(), handler); 

     } catch (Exception e) { 
      return null; 
     } 
     return handler.getfolder(); 
    } 

} 

Basefeedparser.java

public abstract class BaseFeedParser implements SentParser { 

    // names of the XML tags 
    static final String Folder = "Folder"; 
    static final String SchoolName = "SchoolName"; 
    static final String Contact = "Contact"; 
    static final String Parent = "Parent"; 
    static final String ParentCode = "ParentCode"; 
    static final String FamilyCode = "FamilyCode"; 
    static final String FamilyName = "FamilyName"; 
    static final String GivenNames = "GivenNames"; 
    static final String ParentType = "ParentType"; 
    static final String EmailAddress = "EmailAddress"; 
    static final String MobilePhone = "MobilePhone"; 
    static final String LandLineNumber = "LandLineNumber"; 
    static final String Primary = "Primary"; 
    static final String Student = "Student"; 
    static final String StudentCode = "StudentCode"; 
    static final String SchoolYearLevel = "SchoolYearLevel"; 
    static final String RollClass = "RollClass"; 
    static final String House = "House"; 

    // 

    final URL feedUrl; 

    protected BaseFeedParser(String feedUrl) { 
     try { 
      this.feedUrl = new URL(feedUrl); 
     } catch (MalformedURLException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    protected InputStream getInputStream() { 
     try { 
      return feedUrl.openConnection().getInputStream(); 
     } catch (IOException e) { 
      return null; 
     } 
    } 
} 

調用帶

SaxFeedParser sax = new SaxFeedParser("link");// /check parents.xml 
folder result = sax.parse(); 
在活動的代碼

回答

0

有一兩件事你可以改善:

而不是做

localName.toUpperCase().equalsIgnoreCase(
      BaseFeedParser.Contact.toUpperCase() 

所有的時間,節省BaseFeedParser.Contact爲大寫已經,並轉換localName只有一次進入大寫

localName = localName.toUpperCase(); 
if (localName.equals(BaseFeedParser.Folder)) { 
    // something 
} else if (localName.equals(BaseFeedParser.Contact)) { 
    // something else 
} else if (localName.equals(BaseFeedParser.Parent)) { 
    // something here 
} 

這應該給你有點提速。

如果你知道案件沒有改變,你甚至可以完全忽略大小寫。

另一種技術可能加快字符串比較是使用HashMap

private static final int CASE_FOLDER = 1; 
private static final int CASE_SCHOOLNAME = 2; 
private static final HashMap<String, Integer> MAP = new HashMap<String, Integer>(); 
static { 
    MAP.put("FOLDER", CASE_FOLDER); 
    MAP.put("SCHOOLNAME", CASE_SCHOOLNAME); 
} 

然後做

localName = localName.toUpperCase(); 
int match = MAP.get(localName); 
switch (match) { 
    case CASE_FOLDER: 
     // do something 
     break; 
// etc 
}