Android Java XMLParser 问题

Android Java XMLParser issue

提问人:1011 1110 提问时间:7/13/2023 最后编辑:mkrieger11011 1110 更新时间:7/13/2023 访问量:32

问:

我外包给 openweathermap API 来检索结果。

然后我循环浏览结果,然后当它击中“时区”标签时它崩溃了。

代码如下:

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>

我已经能够记录在循环中看到的名称: 我注销:while

  • 当前
  • 城市
  • 坐标
  • 国家

然后它错误地显示:

原因:java.lang.RuntimeException: org.xmlpull.v1.XmlPullParserException:意外类型 (position:TEXT CA@2:99 in java.io.InputStreamReader@59ac190)

我在某处读到,如果 xml 采用 UTF-8 BOM,可能会导致此问题。但我不认为这里是这种情况。

这里可能有什么问题?

java android xml xml 解析

评论

0赞 Robert 7/13/2023
我会将 InputStream 数据保存到一个文件中,然后在十六进制编辑器中保存该文件以查找异常情况。

答:

0赞 1011 1110 7/13/2023 #1

它应该是 parser.next()

不是 parser.nextTag()

1赞 marcinj 7/13/2023 #2

我测试了您的 xml 和您的代码,并得到了不同的异常(但也许 xml 的格式不同):

org.xmlpull.v1.XmlPullParserException:意外类型(position:TEXT CA@3:19 in java.io.InputStreamReader@8152fb6)

这是:

<country>CA</country>

它源自调用,文档中具有:parser.nextTag();

如果 next() 或 START_TAG END_TAG 则调用 next() 并返回事件,否则会引发异常。如果有的话,它将跳过实际标签前的空格 TEXT。

对于标签,您使用 tag,但随后调用 nextTag(),它需要 START 或 END 或空格 TEXT,但找到带有实际文本的 TEXT:CA。这就是异常消息所说的。<country>

一种解决方案是跳过国家和时区标签中的 TEXT:

else if (loopTag.equals("country")) {
    parser.next();
 } else if (loopTag.equals("timezone")) {
     parser.next();
 }

另一种是使用 parser.next 而不是 parser.nextTag。