用xmlpullparser写入Xml文件夹
我是编程中的新手,为了更好地提高我对android中解析xml的理解,我试图从web服务中获取一些关于地震的数据。我已经阅读了*和其他教程中的所有相关主题,但是我的代码中存在错误。 下面是从XML的摘录我想分析:用xmlpullparser写入Xml文件夹
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<q:quakeml xmlns:q="http://quakeml.org/xmlns/quakeml/1.2" xmlns="http://quakeml.org/xmlns/bed/1.2" xmlns:ingv="http://webservices.ingv.it/fdsnws/event/1">
<eventParameters publicID="smi:webservices.ingv.it/fdsnws/event/1/query">
<event publicID="smi:webservices.ingv.it/fdsnws/event/1/query?eventId=16736781">
<type>earthquake</type>
<description>
<type>region name</type>
<text>Tirreno Meridionale (MARE)</text>
</description>
<preferredMagnitudeID>smi:webservices.ingv.it/fdsnws/event/1/query?magnitudeId=49992691</preferredMagnitudeID>
<preferredOriginID>smi:webservices.ingv.it/fdsnws/event/1/query?originId=49089691</preferredOriginID>
<creationInfo>
<agencyID>INGV</agencyID>
<author>SURVEY-INGV</author>
<creationTime>2017-08-16T14:59:48</creationTime>
</creationInfo>
而下面是我写的代码部分:
private static List<Earthquake> extractFeatureFromQuakeml(String earthquakeXML) throws XmlPullParserException, IOException {
XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
xmlFactoryObject.setNamespaceAware(true);
XmlPullParser myparser = xmlFactoryObject.newPullParser();
myparser.setInput(new StringReader(earthquakeXML));
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(earthquakeXML)) {
return null;
}
// Create an empty ArrayList that we can start adding earthquakes to
List<Earthquake> earthquakes = new ArrayList<>();
try {
int eventType = myparser.getEventType();
Log.d("Step", "Started parsing");
while (eventType != XmlPullParser.END_DOCUMENT) {
String location = "";
String time = "";
double magnitude = 0.0;
String url = "";
String tag = myparser.getName();
String text = "";
switch (eventType) {
case XmlPullParser.START_TAG:
//Log.d("Step","Started parsing, end tag: " + tag);
if (tag.equalsIgnoreCase("event")) {
url = myparser.getAttributeValue(null, "publicID");
Log.d(LOG_TAG, "Url" + url);
myparser.next();
}
break;
case XmlPullParser.END_TAG:
text = myparser.getText();
if (text != null) {
if (tag.equalsIgnoreCase("type") && text.equalsIgnoreCase("region name")) {
myparser.nextText();
location = "" + myparser.getText();
Log.d(LOG_TAG, "Location" + location);
}
}
if (tag.equalsIgnoreCase("creationTime")) {
time = "" + myparser.getText();
Log.d(LOG_TAG, "Time" + time);
}
if (tag.equalsIgnoreCase("mag")) {
myparser.next();
myparser.next();
String smagnitude = myparser.getText();
Log.d(LOG_TAG, "Magnitude" + smagnitude);
}
if (tag.equalsIgnoreCase("creationTime")) {
time = "" + myparser.getText();
Log.d(LOG_TAG, "Time" + time);
}
if (tag.equalsIgnoreCase("mag")) {
myparser.next();
myparser.next();
String smagnitude = myparser.getText();
Log.d(LOG_TAG, "Magnitude" + smagnitude);
}
break;
}
// Create a new {@link Earthquake} object with the magnitude, location, time,
// and url from the JSON response.
if (location != null && magnitude != 0.0 && time != null && url != null) {
Earthquake earthquake = new Earthquake(magnitude, location, time, url);
// Add the new {@link Earthquake} to the list of earthquakes.
earthquakes.add(earthquake);
}
eventType = myparser.next();
}
} catch (XmlPullParserException e) {
Log.e("QueryUtils", "Problem parsing the earthquake XML results", e);
}
// Return the list of earthquakes
return earthquakes;
}
现在我得到的唯一的价值是url,其他变量始终为空。 有人可以指出我的代码中的缺陷吗?并且请温柔一点,我已经开始编码仅仅3周前:)
非常感谢!
你的方法的问题是你每次在你的while循环中都是空的,你应该明白while循环会多次调用(例如当你得到Url并将该值存储在url
中,并且你正在调用myparser.next();
所以它会得到下一个元素type
,它会进入while循环现在你正在删除每个值,你也删除url
值。)。
相反,你可以创建一个Earthquake
对象时,你得到的开始标记为event
和每一个结束标签,你可以在Earthquake
对象,并在event
末标签添加coressponding值时,Earthquake
对象添加到列表中。
我很少修改你的代码是如何做到这一点,你可以将所有剩余的值
private static List<Earthquake> extractFeatureFromQuakeml(String earthquakeXML) throws XmlPullParserException, IOException {
XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
xmlFactoryObject.setNamespaceAware(true);
XmlPullParser myparser = xmlFactoryObject.newPullParser();
myparser.setInput(new StringReader(earthquakeXML));
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(earthquakeXML)) {
return null;
}
// Create an empty ArrayList that we can start adding earthquakes to
List<Earthquake> earthquakes = new ArrayList<>();
try {
int eventType = myparser.getEventType();
Log.d("Step", "Started parsing");
Earthquake earthquake = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
// String location = "";
// String time = "";
// double magnitude = 0.0;
// String url = "";
String tag = myparser.getName();
String text = "";
switch (eventType) {
case XmlPullParser.START_TAG:
//Log.d("Step","Started parsing, end tag: " + tag);
if (tag.equalsIgnoreCase("event")) {
url = myparser.getAttributeValue(null, "publicID");
Log.d(LOG_TAG, "Url" + url);
myparser.next();
// We are creating Earthquake here
earthquake = new Earthquake();
earthquake.setUrl(url);
}
break;
case XmlPullParser.END_TAG:
text = myparser.getText();
if (text != null) {
if (tag.equalsIgnoreCase("type") && text.equalsIgnoreCase("region name")) {
myparser.nextText();
earthquake.setLocation(myparser.getText());
Log.d(LOG_TAG, "Location" + earthquake.getLocation());
}
}
if (tag.equalsIgnoreCase("creationTime")) {
earthquake.setTime(myparser.getText());
// time = "" + myparser.getText();
Log.d(LOG_TAG, "Time" + earthquake.getTime());
}
if (tag.equalsIgnoreCase("mag")) {
myparser.next();
myparser.next();
earthquake.setMagnitude(myparser.getText());
// String smagnitude = myparser.getText();
Log.d(LOG_TAG, "Magnitude" + earthquake.getMagnitude());
}
if (tag.equalsIgnoreCase("event")) {
earthquakes.add(earthquake);
}
break;
}
eventType = myparser.next();
}
} catch (XmlPullParserException e) {
Log.e("QueryUtils", "Problem parsing the earthquake XML results", e);
}
// Return the list of earthquakes
return earthquakes;
}
非常感谢!我知道我的代码背后的逻辑是错误的,你的更有道理:D尽管如此,即使在将代码改为建议之后,阅读日志我也只能得到空值,除了url,也许我正在使用xmlpullparser的方法不正确的..让我感到厌烦的是getAttributeValue()方法返回一些东西,而getText()总是为空。但坦克你再帮助一个陌生人了解阅读xmls的基础知识:D – Hrothgah
@Hrothgah,你可以在你的问题中更新你的最新代码..? –
从您的建议开始,我设法解决了这个问题。 我对parser.next()方法的工作原理做了一个错误的假设,我认为当“游标”位于开始标记 时,您可以阅读简单地调用parser.getText()方法的文本;相反,我必须进一步将光标放在文本元素上才能读取它。 另外,但我不知道是否这是特定的xml特有的东西,在结束标记后,next()方法返回一个文本(“/ n”),所以当调用getName()方法返回null 。 – Hrothgah
而不是使用XmlPullParserFactory和XmlPullParser。您可以使用XML转换器来使用Retrofit库。请整合翻新并遵循https://futurestud.io/tutorials/retrofit-how-to-integrate-xml-converter – Rajesh