#android #xml #parsing #sax #saxparser
#Android #xml #синтаксический анализ #sax #saxparser
Вопрос:
Я разрабатываю приложение для Android, и мне нужно проанализировать XML-файл, мне сказали, что SAX parsers лучше подходят для мобильных устройств, чтобы я пытался его использовать, но я застрял. Вот XML-код:
<current_conditions>
<condition data="Clear"/>
<temp_f data="50"/>
<temp_c data="10"/>
<humidity data="Humidity: 76%"/>
<icon data="/ig/images/weather/sunny.gif"/>
<wind_condition data="Wind: NE at 14 mph"/>
</current_conditions>
<forecast_conditions>
<day_of_week data="Tue"/> ****
<low data="43"/>
<high data="64"/> ****
<icon data="/ig/images/weather/mostly_sunny.gif"/>
<condition data="Mostly Sunny"/>
</forecast_conditions>
<forecast_conditions>
<day_of_week data="Wed"/>
<low data="43"/>
<high data="64"/>
<icon data="/ig/images/weather/sunny.gif"/>
<condition data="Clear"/>
</forecast_conditions>
Я пытаюсь получить значения только двух тегов с * рядом, но вместо этого он возвращает значения в конце документа. Как мне решить эту проблему, поскольку мне нужны только определенные значения в XML. Вот мой код:
public class ExampleHandler extends DefaultHandler {
private boolean in_in_current_conditions = false;
private boolean in_in_forecast_conditions = false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
@Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException
{
if (localName.equals("forecast_information"))
{
this.in_forecast_information = true;
}
else if (localName.equals("current_conditions"))
{
this.in_in_current_conditions = true;
}
else if (localName.equals("forecast_conditions"))
{
this.in_in_forecast_conditions = true;
}
else if (localName.equals("high")) {
if (this.in_in_forecast_conditions)
{
String attrValue = atts.getValue("data");
myParsedExampleDataSet.setCurrtempValue(attrValue);
}
} else if (localName.equals("day_of_week")) {
if (this.in_in_forecast_conditions) {
String attrValue1 = atts.getValue("data");
myParsedExampleDataSet.setLowValue(attrValue1);
}
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("forecast_information")) {
this.in_forecast_information = false;
} else if (localName.equals("current_conditions")) {
this.in_in_current_conditions = false;
} else if (localName.equals("forecast_conditions")) {
this.in_in_forecast_conditions = false;
}
}
@Override
public void characters(char ch[], int start, int length) {
}
}
Ответ №1:
На вашем месте я бы просто использовал Simple XML framework для выполнения работы по синтаксическому анализу XML за вас. Тогда было бы не слишком сложно просто создать несколько объектов, которые могли бы извлекать эти данные из XML.
P.S. Я использую Simple project для всего своего XML, поэтому я даже написал сообщение в блоге, объясняющее, как использовать его в проектах Android: вы можете прочитать его здесь.
Ответ №2:
Чтобы получить эти два значения, вы должны сделать что-то вроде этого:
public class ExampleHandler extends DefaultHandler {
private static final String FORECAST_CONDITION = "forecast_condition";
private boolean day_of_week_dataWanted = false;
private boolean high_dataWanted = false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
public ExampleHandler() {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(FORECAST_CONDITION.equals(localName)){
if("day_of_week".equals(localName)){
day_of_week_dataWanted = true;
}
if("high".equals(localName)){
high_dataWanted = true;
}
}
}
@Override
public void characters(char ch[], int start, int length) {
if(day_of_week_dataWanted){
myParsedExampleDataSet.setLowValue(new String(ch, start, length));
day_of_week_dataWanted = false;
}
if(high_dataWanted){
myParsedExampleDataSet.setCurrtempValue(new String(ch, start, length));
high_dataWanted = false;
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
}
}
Но есть более изящные решения, на которые вы могли бы взглянуть, надеюсь, это даст вам подсказку.
Комментарии:
1. Вы хотите знать, когда вы находитесь в каждом XML-элементе, и сохранить их все в свой ‘ParsedExampleDataSet’, чтобы вы могли использовать их, если они вам понадобятся позже. Возможно, сохраните их на карте. Вышесказанное дает вам то, что вам было нужно, верно?
2. Нет, он не вернул никаких значений. Мне нужно получить 4 значения для текущего дня и два для следующего дня. Я уже могу получить значения за текущий день. Я хочу отображать их сразу же, как они будут прочитаны
3. Вы не должны отображать их немедленно. Анализатор XML заполняет ваш объект myParsedExampleDataSet, затем вы вызываете getParsedData() и можете получить доступ к своим переменным.
4. Да, именно так я это делаю, но я все еще не могу получить значения на следующий день, потому что есть серия тегов с одинаковым именем
Ответ №3:
Я отсортировал это, используя заполнение значений в массивах, и когда я хочу их отобразить, я просто использую их положение в массиве для их вызова