SaxParser как один из наиболее удобных и быстрых парсеров

Ответить
Аватара пользователя
knight
Сообщения: 44
Зарегистрирован: 21 сен 2012, 09:25

SaxParser как один из наиболее удобных и быстрых парсеров

Сообщение knight » 20 июл 2013, 15:21

Всем привет, так как обычно завален работой, а иногда просто хочется где-то погулять в свободное время, то все ненахожу времени поделится со своими наработками с другими, но вот сегодня всетаки вырвал время, и давно хотел написать про Секс)) парсер, так как ненаходил его описание сдесь.

Собственно разрабатываю я высоко нагруженную систему под андроид, и мне приходят иногда тонны xmlя, естественно даже тогда начиная только разрабатывать под андроид (месяцев 6 назад) я сразу же начал читать статьи про то какой парсер использовать лучше, пришел к выводу что Sax. долго я искал примеры чтобы понять как жи сие чудо работает.

Собственно пишется он отдельным классом который наследуется от DefaultHandler

есть у нас допустим такая xml

<organizations>
<organization>
<or_id>1</or_id>
<or_name>Ололо</or_name>
</organization>
<organization>
<or_id>2</or_id>
<or_name>Ололо2</or_name>
</organization>
</organizations>
<progects>
<progect>
<pr_id>34</pr_id>
<pr_name>Проект1</pr_name>
<or_parent_id>1</or_parent_id>
</progect>
<progect>
<pr_id>36</pr_id>
<pr_name>Проект2</pr_name>
<or_parent_id>2</or_parent_id>
</progect>
</progects>

впринцепи для примера хватит, теперь опишим наш класс для парсинга такой штуки

Код: Выделить всё


public class SAXparsNews extends DefaultHandler {

	Project pr ;
	Organization or ;
        ArrayList<Project> projects = new ArrayList<Project>();
        ArrayList<Organization> organizations = new ArrayList<Organization>();

	// для запоминания позиции тега
	String thisElement = "";

	
	
	@Override
	public void startDocument() throws SAXException {
		System.out.println("Start parse XML...");
	}

	@Override
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) throws SAXException {
		thisElement = qName;
		//как только мы встречаем нужный элемент мы создаем новый обьект к нему
		if (qName.equalsIgnoreCase("organization")) {
			or = new Organization();
		}
		if (qName.equalsIgnoreCase("project")) {
			pr = new Project();
		}

		
	}


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

		//встречаем конец елемента и добавляем инициализированны обьект в коллекцию

		if (qName.equalsIgnoreCase("organization")) {
			organizations.add(or);
		}
		if (qName.equalsIgnoreCase("project")) {
			projects.add(pr);
		}

	
		//обнуляем текущию позицию елемента
		thisElement = "";
	}

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


		//ловим нужный елемент и заполняем обьект данными
		if (thisElement.equals("or_id")) {
			or.or_id = or.or_id+ new String(ch, start, length);
		}
		if (thisElement.equals("or_name")) {
			or.or_name = or.or_name + new String(ch, start, length);
		}

		if (thisElement.equals("pr_id")) {
			pr.id = pr.id + new String(ch, start, length);
		}
		if (thisElement.equals("pr_name")) {
			pr.pr_name = pr.pr_name + new String(ch, start, length);
		}
		if (thisElement.equals("or_parent_id")) {
			pr.or_parent_id = pr.or_parent_id+ new String(ch, start, length);
		}
		
		
			
			
			
	}


	public ArrayList<Organization> GetOrganizations()
	{

  	return organizations;
	}

	public ArrayList<Project> GetProjectss()
	{

  	return projects;
	}

	@Override
	public void endDocument() {
		System.out.println("Stop parse XML...");
		
	}
}
методы GetOrganizations(),GetProjectss() реализованы для удобства чтобы забрать нужные коллекции после того как парсер отработает и вернет нам эти обьекты, если они есть конечно. далее мы можем положить их в базу ну или че вы там хотите, или можно выполнить данные операции в методе endDocument()

через Attributes atts можно забрать елементы тега
если они в таком виде <organization or_id="1">
or_id="1" , будет в атрибутах.

благодаря такой системе можно забирать нужные любые вам данные из xml


собственно использование вашего написанного класса

Код: Выделить всё

SAXParserFactory factory = SAXParserFactory.newInstance();
 SAXParser parser = null;
  try {
    parser = factory.newSAXParser();
       } catch (ParserConfigurationException e1) {
       // TODO Auto-generated catch block
      e1.printStackTrace();
      } catch (SAXException e1) {
      // TODO Auto-generated catch block
     e1.printStackTrace();
     }
     SAXparsNews saxp = new SAXparsNews(); // наш класс парсинга

     try {
          parser.parse(new InputSource(
           new StringReader(otvet), saxp);
          } catch (SAXException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
	} catch (IOException e) {
	// TODO Auto-generated catch block
           e.printStackTrace();
	}


          saxp.GetOrganizations();
          saxp.GetProjectss() 

переменная otvet String содержит строку xml которая приходит от сервера

вот собственно и все, будут вопросы пишите

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: SaxParser как один из наиболее удобных и быстрых парсеро

Сообщение rezak90 » 20 июл 2013, 16:03

Ну честно вы не америку открыли, и андроид к сакс парсеру не имеет никакого отношения, чистая джава и зная джаву каждый знает для чего сакс парсер а для чего дом...
Но надеюсь что хоть кому то эта статья будет полезной.
R.id.team
Политика на форуме запрещена

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: SaxParser как один из наиболее удобных и быстрых парсеро

Сообщение Mikhail_dev » 20 июл 2013, 16:41

Начнем с того, что SAX парсер это скорее тип парсера, а не парсер. Jackson в андроиде на сколько я знаю как раз работает по типу SAX парсера. А дефолтный в андроиде, работает по DOM.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: SaxParser как один из наиболее удобных и быстрых парсеро

Сообщение rezak90 » 20 июл 2013, 16:44

та все парсеры делятся на линейный и не линейный, линейные проходят от начала и до конца, не линейные делают выборку по указанному элементу... соответственно если файл большой то лучше использовать линейный... так же есть парсеры построенные на рефлексии, например такие как Gson, они хороши для маленьких объектов, для больших он слишком медленный.
R.id.team
Политика на форуме запрещена

Ответить