Разбор XML и получение информации Несколько уровней узлов Deep Java / Android - PullRequest
0 голосов
/ 10 декабря 2010

Я работаю на примере моего профессора, который получает данные с сайта прогноза погоды и анализирует XML-файл, чтобы показать погодные условия в списке. Моя программа похожа, но я хочу получить информацию, которая вложена в несколько узлов, и я не знаю, как к ней добраться. Вот файл XML, из которого я работаю:

<?xml version="1.0" encoding="UTF-8"?> 
<DirectionsResponse> 
 <status>OK</status> 
 <route> 
  <summary>S Street Viaduct</summary> 
  <leg> 
   <step> 
    <travel_mode>DRIVING</travel_mode> 
    <start_location> 
     <lat>40.7021400</lat> 
     <lng>-74.0158200</lng> 
    </start_location> 
    <end_location> 
     <lat>40.7021400</lat> 
     <lng>-74.0158200</lng> 
    </end_location> 
    <polyline> 
     <points>kslwFzewbM</points> 
     <levels>B</levels> 
    </polyline> 
    <duration> 
     <value>0</value> 
     <text>1 min</text> 
    </duration> 
    <html_instructions>Head &lt;b&gt;east&lt;/b&gt; on &lt;b&gt;S Street Viaduct&lt;/b&gt;</html_instructions> 
    <distance> 
     <value>0</value> 
     <text>1 ft</text> 
    </distance> 
   </step> 
   <duration> 
    <value>0</value> 
    <text>1 min</text> 
   </duration> 
   <distance> 
    <value>0</value> 
    <text>1 ft</text> 
   </distance> 
   <start_location> 
    <lat>40.7021400</lat> 
    <lng>-74.0158200</lng> 
   </start_location> 
   <end_location> 
    <lat>40.7021400</lat> 
    <lng>-74.0158200</lng> 
   </end_location> 
   <start_address>S Street Viaduct, New York, NY 10004, USA</start_address> 
   <end_address>S Street Viaduct, New York, NY 10004, USA</end_address> 
  </leg> 
  <copyrights>Map data ©2010 Google, Sanborn</copyrights> 
  <overview_polyline> 
   <points>kslwFzewbM</points> 
   <levels>B</levels> 
  </overview_polyline> 
 </route> 
</DirectionsResponse> 

Меня действительно интересует только извлечение информации в теге "html_instructions", но она вложена в теги "route", "leg" и "step". Я видел несколько уроков и вопросов по SO для разбора XML, но, похоже, не смог найти решения для этого. Любое направление будет с благодарностью!

Спасибо.

Ответы [ 2 ]

4 голосов
/ 11 декабря 2010

Таким образом, использование SAX-парсера в целом является хорошим выбором (он быстрый, позволяет отфильтровывать все ненужные данные, использует мало памяти). При работе с SAX в первый раз может оказаться полезным следующий пример. Я не говорю, что код идеален (он пропускает, например, обработку исключений, безопасное закрытие потока и т. Д.), Но это может быть хорошей отправной точкой для вас.


import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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

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

public class Test {

  private static final String HTML_INSTRUCTIONS = "html_instructions";

  public static void main(String[] args) throws Exception {
    final List htmlInstructions = new ArrayList();

    SAXParserFactory spf = SAXParserFactory.newInstance();
    SAXParser sp = spf.newSAXParser();
    DefaultHandler dh = new DefaultHandler() {
      private boolean isHtmlInstructions = false;
      private StringBuilder sb = new StringBuilder();
      @Override
      public void startElement(String uri, String localName, String name,
          Attributes attributes) throws SAXException {
        super.startElement(uri, localName, name, attributes);
        if (HTML_INSTRUCTIONS.equals(name)) {
          isHtmlInstructions = true;
        }
      }

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

      @Override
      public void endElement(String uri, String localName, String name)
          throws SAXException {
        super.endElement(uri, localName, name);
        if (HTML_INSTRUCTIONS.equals(name)) {
          htmlInstructions.add(sb.toString());
          sb.delete(0, sb.length());
          isHtmlInstructions = false;
        }
      }
    };

    InputStream is = new FileInputStream("test.xml");
    sp.parse(is, dh);
    for (String htmlInstruction : htmlInstructions) {
      System.out.println(htmlInstruction);
    }

  }

}

Вывод должен выглядеть следующим образом:


Head <b>east on <b>S Street Viaduct</b>

3 голосов
/ 11 декабря 2010

Используйте SAX и обращайте внимание только на тег html_instructions.Ваш обработчик будет вызываться с startElement() для каждого элемента и передается в имени элемента.Сравните это имя с "html_instructions".Если у вас есть совпадение, обратите внимание на все обработанные узлы до соответствующего вызова endElement().

...