Android Java XML解析问题

huangapple go评论51阅读模式
英文:

Android Java XMLParser issue

问题

我正在外包给openweathermap API以检索结果。

然后我循环遍历结果,当遇到"timezone"标签时程序崩溃。

以下是代码部分:

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);

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循环中记录标签名称,如下所示:

  • 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)

我曾在某处读到,如果XML是UTF-8 BOM格式,可能会导致此问题。但我不认为这是问题的原因。

这里可能的问题是什么?

英文:

Im outsourcing to openweathermap API to retrieve results.

I then loop through the results and then it crashes when it hits the "timezone" tag.

Here is the code:

URL url = new URL(&quot;https://api.openweathermap.org/data/2.5/weather?q=toronto,ca&amp;APPID=***&amp;mode=xml&amp;units=metric&quot;);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod(&quot;GET&quot;);
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(&quot;weather&quot;, loopTag);
        if (loopTag.equals(&quot;temperature&quot;)) {
            min = parser.getAttributeValue(null, &quot;min&quot;);
            max = parser.getAttributeValue(null, &quot;max&quot;);
            curr = parser.getAttributeValue(null, &quot;value&quot;);
        } else if (loopTag.equals(&quot;weather&quot;)) {
            icon = parser.getAttributeValue(null, &quot;icon&quot;);
        }
    }
    parser.nextTag();
}

The xml trying to retrieve data:

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

I've been able to log the names as can be seen in the while loop:
I log out:

  • current
  • city
  • coord
  • country

Then it errors out with:

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

I've read somewhere that if the xml is in UTF-8 BOM it can cause this issue. But I don't think it is the case here.

What could be the issue here?

答案1

得分: 1

> org.xmlpull.v1.XmlPullParserException: 意外类型(位置:java.io.InputStreamReader@8152fb6 中的TEXT CA@3:19)

这是由于:

&lt;country&gt;CA&lt;/country&gt;

它源自parser.nextTag(); 调用,根据文档,该方法有:

> 调用next()并返回事件,如果是START_TAG或END_TAG,则返回事件,否则抛出异常。如果有的话,它将跳过实际标签之前的空白TEXT。

&lt;country&gt;标签的情况下,您消耗了<country>标签,但然后调用nextTag(),它期望的是START或END或空白TEXT,但找到了带有实际文本CA的TEXT。这就是异常消息所说的内容。

一种解决方法是跳过country和timezone标签中的TEXT:

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

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

英文:

I tested your xml and your code and I got different exception (but maybe the xml is differently formatted):

> org.xmlpull.v1.XmlPullParserException: unexpected type (position:TEXT CA@3:19 in java.io.InputStreamReader@8152fb6)

which is :

&lt;country&gt;CA&lt;/country&gt;

it originates from the parser.nextTag(); call which in documentation has:

> Call next() and return event if it is START_TAG or END_TAG otherwise throw an exception. It will skip whitespace TEXT before actual tag if any.

in the case of &lt;country&gt; tag you consume <country> tag, but then call nextTag() which expect either START or END or whitespace TEXT but finds TEXT with actuall text: CA. Which is what the exception message is saying.

One solution is to skip the TEXT in country and timezone tags:

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

the other is to use parser.next instead of parser.nextTag.

答案2

得分: 0

应该是 parser.next(),而不是 parser.nextTag()。

英文:

its supposed to be parser.next()

not parser.nextTag()

huangapple
  • 本文由 发表于 2023年7月13日 00:25:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672674.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定