You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android解析OpenWeatherMap XML数据时触发XmlPullParserException崩溃

问题

调用OpenWeatherMap API获取天气数据,使用XmlPullParser循环解析XML结果时,程序在即将处理timezone标签时崩溃。日志显示已成功解析current、city、coord、country标签,随后报错:

Caused by: java.lang.RuntimeException: org.xmlpull.v1.XmlPullParserException: unexpected type (position:TEXT CA@2:99 in java.io.InputStreamReader@59ac190)

已排除UTF-8 BOM导致问题的可能,求故障原因及解决办法。

相关代码及返回XML结构如下:

原代码

URL url = new URL("https://api.openweathermap.org/data/2.5/weather?q=toronto,ca&APPID=***&mode=xml&units=metric");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query.
conn.connect();
InputStream is = conn.getInputStream();

XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);

while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
    if(parser.getEventType() == XmlPullParser.START_TAG) {
        String loopTag = parser.getName();
        Log.i("weather", loopTag);
        if (loopTag.equals("temperature")) {
            min = parser.getAttributeValue(null, "min");
            max = parser.getAttributeValue(null, "max");
            curr = parser.getAttributeValue(null, "value");
        } else if (loopTag.equals("weather")) {
            icon = parser.getAttributeValue(null, "icon");
        }
    }
    parser.nextTag();
}

返回的XML数据

<current>
    <city id="6167865" name="Toronto">
       <coord lon="-79.4163" lat="43.7001"/>
       <country>CA</country>
       <timezone>-14400</timezone>
       <sun rise="2023-07-12T09:46:54" set="2023-07-13T00:59:13"/>
    </city>
    <temperature value="20.57" min="19.15" max="21.94" unit="celsius"/>
    <feels_like value="20.28" unit="celsius"/>
    <humidity value="61" unit="%"/>
    <pressure value="1013" unit="hPa"/>
    <wind>
        <speed value="1.79" unit="m/s" name="Light breeze"/>
        <gusts value="4.47"/>
        <direction value="314" code="NW" name="Northwest"/>
    </wind>
    <clouds value="98" name="overcast clouds"/>
    <visibility value="10000"/>
    <precipitation mode="no"/>
    <weather number="804" value="overcast clouds" icon="04d"/>
    <lastupdate value="2023-07-12T15:07:14"/>
</current>

故障原因与解决方案

核心原因

代码中使用的parser.nextTag()方法只会跳过到下一个标签(START_TAG或END_TAG),但会忽略标签之间的文本节点(比如country标签内的CA文本)。当解析完country的START_TAG后,调用nextTag()会尝试跳过CA文本直接查找下一个标签,而nextTag()在遇到TEXT类型节点时会直接抛出异常,这就是报错的根源。

解决办法

将循环里的parser.nextTag()替换为parser.next(),该方法会处理所有XML事件类型(包括TEXT、END_TAG等),确保不会因跳过非标签节点导致异常。

修改后的代码示例

URL url = new URL("https://api.openweathermap.org/data/2.5/weather?q=toronto,ca&APPID=***&mode=xml&units=metric");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();

XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);

int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
    if(eventType == XmlPullParser.START_TAG) {
        String loopTag = parser.getName();
        Log.i("weather", loopTag);
        if (loopTag.equals("temperature")) {
            min = parser.getAttributeValue(null, "min");
            max = parser.getAttributeValue(null, "max");
            curr = parser.getAttributeValue(null, "value");
        } else if (loopTag.equals("weather")) {
            icon = parser.getAttributeValue(null, "icon");
        }
    }
    // 使用next()替代nextTag(),处理所有事件类型
    eventType = parser.next();
}

额外说明

如果需要读取标签内的文本内容(比如timezone的-14400),可以在遇到对应START_TAG后,调用parser.nextText()获取文本,该方法会自动跳过到对应的END_TAG,示例如下:

if (loopTag.equals("timezone")) {
    String timezoneValue = parser.nextText();
    Log.i("weather", "timezone: " + timezoneValue);
}

内容的提问来源于stack exchange,提问作者1011 1110

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:49:55