Разбор xml из интернета (yr.no) - PullRequest
0 голосов
/ 29 февраля 2012

У меня нет опыта разбора xml, поэтому, возможно, некоторые вещи, которые я пишу, для некоторых выглядят глупо, и, возможно, некоторые из моих терминов не совсем верны. Пожалуйста, прости.

Я разрабатываю приложение для Android, которое, помимо прочего, должно анализировать данные о погоде из YR.no . Эта организация предлагает API с методами, которые предоставляют определенные данные в формате XML. Допустим, например, что я хочу проанализировать данные XML из этого http://api.yr.no/weatherapi/seaapproachforecast/1.0/?location=stad

Я разработал код, который может выполнять некоторый анализ XML, и он работает прямо в этом http://www.w3schools.com/xml/simple.xml (в качестве теста).

Основные строки кода, определяющие, что нужно получить в моем классе BaseFeedParser:

RootElement root2 = new RootElement("breakfast_menu");
Element food = root2.getChild("food");
Element name = food.getChild("name");

food.setEndElementListener(new EndElementListener() {
    public void end() {
        messages.add(currentMessage.copy());
    }
});

food.getChild("name").setEndTextElementListener(new EndTextElementListener() {
    public void end(String body) {
        currentMessage.setTitle(body);
    }
});

try {
    Xml.parse(this.getInputStream(), Xml.Encoding.ISO_8859_1, root2.getContentHandler());
} catch (Exception e) {
    throw new RuntimeException(e);
}
return messages;

А потом из моего занятия:

@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);
    loadFeed();
}

private void loadFeed() {
    try {
        BaseFeedParser parser = new BaseFeedParser();
        messages = parser.parse();
        List<String> titles = new ArrayList<String>(messages.size());
        System.out.println(messages.size());
        for (Message msg : messages) {
            titles.add(msg.getTitle());
        }
        ArrayAdapter<String> adapter = 
                new ArrayAdapter<String>(this, R.layout.row,titles);
        this.setListAdapter(adapter);
        String str = "!";
        if (titles != null) {
            str = titles.toString();
            System.out.println("not null");
            System.out.println(str);
        }

        test(str);
    } catch (Throwable t) {
        Log.e("AndroidNews",t.getMessage(), t);
    }
}

public void test(String s) {
    setContentView(R.layout.error);
    TextView textView = (TextView) findViewById(R.id.mytextview); 
    textView.setText(s);
}

Таким образом, он возвращает и печатает нужные мне данные («бельгийские вафли» и т. Д.)

Моя проблема с данными yr.no, которые я первоначально хотел проанализировать, состоит в том, что каждый конечный дочерний элемент не содержит только одного значения, но может иметь больше тегов (например, <waveDirection unit="degree" value="250"/>). Поэтому, когда я изменяю элементы, чтобы использовать этот, он заканчивается 25 различными String с (что, если вы считаете, все разные потомки с тегом waveDirection), но каждое значение пусто (как String a = ""). Я не получаю ошибки, я просто получаю список из 25 пустых строк. То, как я пытаюсь достичь своей стихии, выглядит примерно так:

RootElement root = new RootElement("weatherdata");
Element product = root.getChild("product");
Element time = product.getChild("time");
Element location = time.getChild("location");

location .setEndElementListener(new EndElementListener(){
public void end() {
        messages.add(currentMessage.copy());            
    }
});

location.getChild("windDirection").setEndTextElementListener(new EndTextElementListener() {
    public void end(String body) {
        currentMessage.setTitle(body);
    }
});

Так как мне изменить это, чтобы оно работало с этим xml? Я не предоставляю все классы и методы (например, setTitle()), но я думаю, что они работают, так как они правильно разбирают мой первый тестовый XML. И я полагаю, что я правильно установил feedUrlString = "http://api.yr.no/weatherapi/seaapproachforecast/1.0/?location=stad";, поскольку он находит корень документа и 25 элементов.

РЕДАКТИРОВАТЬ: Я сделал это! Правильный способ получить атрибуты - использовать:

    location.setStartElementListener(new StartElementListener(){
        public void start(Attributes attributes){
            messages.add(currentMessage.copy());            
        }
    });

    location.getChild("windDirection").setTextElementListener(new TextElementListener(){
    public void end(String body) {
        //currentMessage.setTitle(body);
        //System.out.println("b="+ body);
        }

    @Override
    public void start(Attributes attributes) {
            System.out.println("val" + attributes.getValue("deg"));
            currentMessage.setTitle(attributes.getValue("deg"));
        }
    });

Так что теперь я получаю свои данные, но по какой-то причине все, кроме самого последнего элемента (я также проверил его на других YR.no xmls) .. Должна быть какая-то ошибка, которую я должен решить, но главный шаг сделан. Спасибо всем за ответы и особенно user306848, который указал мне направление, которое я использовал!

Ответы [ 3 ]

2 голосов
/ 29 февраля 2012

Используйте Dom Parser ....... Это будет легко ...

См. Здесь учебник,

http://www.roseindia.net/xml/dom/

1 голос
/ 29 февраля 2012

Я думаю, ваш код предполагает наличие текстового узла, представляющего значения, которые вы ищете.Это не относится к файлу xml из домена yr.no.

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

У меня нет опытас развитием Android, но вы используете пакет android.sax?Тогда я думаю, что android.sax.StartElementListener будет хорошим кандидатом.Он получает атрибуты, принадлежащие определенному тегу.

1 голос
/ 29 февраля 2012

Используйте этот пример .

Он использует XML-файл, хранящийся локально. Если вы получаете XML Feed, измените код на следующий:

  URL url = new URL("ENTER XML LINK");
  InputStream stream = url.openStream();
  Document doc = docBuilder.parse(stream);
...