Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Java - SAXParser не сохраняет аррайлист((( ?


Автор: Wardrag 19.10.2011, 11:55
Ребятки,спасайте,не работает(.Задача такая - пройтись по вложенным тегам и спарсить их в аррайлист в виде полей одного объекта.Допустим,такой пример:

<myentry>
<id>1</id>
<name>Sergei</name>
<address>Roy Street</address>
<tel>55547458</tel>
</myentry>

Всё что между <myentry> и </myentry> нужно сохранить в аррайлист.Я решил воспользоваться сакспарсером,так как он показался мне куда проще чем остальные.Код для удобочитаемости закинул сюда:

http://pastebin.com/hjutKAAP

В течение парсинга он должен сохранять каждый новый объект после срабатывания нового события,но этого не происходит.Проблема возникла определить,где заканчивается нужный мне myentry,поэтому я закинул проверку в обработчик EndElement.Мб ещё какие-то варианты есть для решения,казалось бы,ну тривиальнейшей задачи ? Переделывать уже жутко неохота,а разобраться надо.

Автор: LSD 19.10.2011, 12:04
Если коротко, то все неправильно smile Посмотри в FAQ пример использования SAX парсера.

Автор: Wardrag 19.10.2011, 12:30
Я вообще-то по нему и делал)

Добавлено через 53 секунды
http://www.quizful.net/post/sax-parser-java

Автор: LSD 19.10.2011, 13:41
Я вообще про наш FAQ говорил. Как минимум у тебя неправильный endElement(). Плюс в примере и у тебя неправильный characters().
В characters() надо накапливать символы в буффер, а уже в endElement() присваивать конкретному полю.

Добавлено через 2 минуты и 23 секунды
Ну и конечно хранить список всех объектов в самом объекте это конечно оригинально smile , но работать не будет.

Автор: Wardrag 19.10.2011, 16:14
Эх,лучше в лс отпишу)

Автор: LSD 20.10.2011, 14:43
Код

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class App {
    public static void main(String[] args) {
        try {
            exec();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    private static void exec() throws Exception {
        String xml = "<spreadSheets><spreadSheet><id>1</id><content>abc</content><link>http://google.com</link></spreadSheet><spreadSheet><id>2</id><content>def</content><link>http://google.com</link></spreadSheet></spreadSheets>";
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        SAXHandler handler = new SAXHandler();
        parser.parse(new InputSource(new StringReader(xml)), handler);

        for (GoogleSpreadSheet googleSpreadSheet : handler.getGoogleSpreadSheets()) {
            System.out.println("    "+googleSpreadSheet);
        }
    }

    public static class SAXHandler extends DefaultHandler {
        private ArrayList<GoogleSpreadSheet> googleSpreadSheets;
        private GoogleSpreadSheet currentGoogleSpreadSheet;
        private StringBuffer buffer;

        public List<GoogleSpreadSheet> getGoogleSpreadSheets() {
            return googleSpreadSheets == null ? Collections.<GoogleSpreadSheet>emptyList() : Collections.unmodifiableList(googleSpreadSheets);
        }

        @Override
        public void startDocument() throws SAXException {
            System.out.println("Started Reading XML...");
            googleSpreadSheets = new ArrayList<GoogleSpreadSheet>();
            buffer = new StringBuffer();
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if (qName.equals("spreadSheet")) {
                if (currentGoogleSpreadSheet != null) {
                    throw new SAXException("Malformed XML");
                }
                currentGoogleSpreadSheet = new GoogleSpreadSheet();
            }
            buffer.setLength(0);
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            buffer.append(ch, start, length);
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if (qName.equals("id")) {
                currentGoogleSpreadSheet.id = buffer.toString();
            } else if (qName.equals("content")) {
                currentGoogleSpreadSheet.content = buffer.toString();
            } else if (qName.equals("link")) {
                currentGoogleSpreadSheet.link = buffer.toString();
            } else if (qName.equals("spreadSheet")) {
                googleSpreadSheets.add(currentGoogleSpreadSheet);
                currentGoogleSpreadSheet = null;
            }
            buffer.setLength(0);
        }

        @Override
        public void endDocument() throws SAXException {
            System.out.println("Ended Reading XML...");
            buffer = null;
        }
    }

    public static class GoogleSpreadSheet {
        public String id;
        public String content;
        public String link;

        @Override
        public String toString() {
            return "GoogleSpreadSheet{" +
                   "id='" + id + '\'' +
                   ", content='" + content + '\'' +
                   ", link='" + link + '\'' +
                   '}';
        }
    }
}

Автор: Wardrag 21.10.2011, 17:57
   Ох,интересно получилось )).А если нужно какой-то вложенный  тег ещё и параллельно искать (взависимости от введенной команды в консоли,например,link 'http://ссылка' в консоли) ? Ведь это же каждый раз надо будет определять как-то,ввёл ли пользователь аргументы или нет,сколько их и производить поиск значения аргумента.Я понимаю,как это реализовать,но не понимаю,как это связать с парсингом,ведь он автоматом всё делать будет,т.е. отдельный метод в парсер не добавишь,он не будет вызван....? Если бы был свой owned парсер,то на вход функции поиска можно было бы передать аргументы и значения,какие надо искать,а как сделать здесь?(

Автор: LSD 24.10.2011, 12:02
Что мешает добавить в SAXHandler дополнительную логику, чтобы он искал только теги с заданным именем, а все остальные ингорировал?

Автор: Welemir 24.10.2011, 13:47
  

Автор: LSD 24.10.2011, 14:14
Если у тебя есть XML, и надо последовательно выполнять к нему запросы. То имеет смысл распарсить его один раз в DOM, а дальше или вручную проходится по нему, или использовать XPath.

Автор: Wardrag 24.10.2011, 21:55
Так почему не работает то ?

Автор: LSD 25.10.2011, 11:19
Не работает что?

Автор: Wardrag 25.10.2011, 11:35
Ладно,не важно ).Проблему оставил другим решать,больше мучить не буду.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)