我一直在阅读有关如何解析XML数据的Android XmlPullParser
上的一些教程。
更具体地说,我正在使用https://gdata.youtube.com/feeds/api/standardfeeds/top_rated
这里我简化部分来自此Feed的条目(我希望不改变结构):
<entry>
<id>http://gdata.youtube.com/feeds/api/videos/abc45678qwe</id>
[...]
<title type='text'>THE TITLE</title>
[...]
<link rel='alternate' type='text/html' href='https://www.youtube.com/watch?v=abc45678qwe&feature=youtube_gdata'/>
[...]
<media:group>
[...]
<media:title type='plain'>THE TITLE</media:title>
<yt:duration seconds='300'/>
[...]
<yt:videoid>abc45678qwe</yt:videoid>
</media:group>
<gd:rating average='1' max='5' min='1' numRaters='1' rel='http://schemas.google.com/g/2005#overall'/>
<yt:statistics favoriteCount='0' viewCount='11111111'/>
<yt:rating numDislikes='111' numLikes='111'/>
</entry>
我成功获得了标题和链接:
private String[] readEntry(XmlPullParser parser)
throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, null, "entry");
String title = null;
String link = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
String rel = parser.getAttributeValue(null, "rel");
if (name.equalsIgnoreCase("title")) {
title = readTitle(parser);
} else if (name.equalsIgnoreCase("link")
&& rel.equals("alternate")) {
link = readLink(parser);
} else {
skip(parser);
}
}
return new String[] { title, link };
}
private String readLink(XmlPullParser parser)
throws XmlPullParserException, IOException {
String link = "";
parser.require(XmlPullParser.START_TAG, null, "link");
link = parser.getAttributeValue(null, "href");
parser.nextTag();
parser.require(XmlPullParser.END_TAG, null, "link");
return link;
}
private String readTitle(XmlPullParser parser)
throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, null, "title");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, null, "title");
return title;
}
但无论我尝试什么,我都无法在<yt:duration seconds='300'/>
的几秒钟内获得持续时间。
显然,使用与上述方法类似的东西无法访问它,因为应该需要处理namespaces
,但我不确定。由于我对此感到失望,所以我们非常感谢任何建议。感谢。
====
编辑:我正在添加我尝试输入标记yt:duration
的内容。
我在skip(parser);
之前添加了其他检查。即:
} else if (name.equalsIgnoreCase("yt:")) {
Utils.logger("i", "entering yt:", TAG);
readDuration(parser)
}
我用"yt:"
或"yt"
更改"yt:duration
但没有结果
还有
String namespace = parser.getNamespace();
并使用name.equalsIgnoreCase...
更改namespace.equalsIgnoreCase...
我没有收到日志条目,所以我甚至没办法尝试这个:
private String readDuration(XmlPullParser parser)
throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, "yt", "duration");
String seconds = parser.getAttributeValue(null, "seconds");
parser.nextTag();
parser.require(XmlPullParser.END_TAG, "yt", "duration");
Utils.logger("i", "duration: " + seconds + " seconds", TAG);
return seconds;
}
根据要求增加。我不确定它是否足够有用。
答案 0 :(得分:0)
XmlPullParser
似乎能够识别名称空间,不同之处在于必须明确设置。根据{{3}}的文档:
指定此工厂生成的解析器将提供 支持XML命名空间。默认情况下,此值设置为 假的。
您可能想尝试该选项。
另外,正如评论中所提到的,我试图在没有问题的情况下遍历您的xml,下面是打印所有持续时间值的源代码(只是为了让您知道,这将作为{运行} {1}}计划,而不是Java
):
ADT
输出我得到:
public static void main(String[] args) throws ParserConfigurationException,
SAXException, IOException {
InputStream path = new URL(
"https://gdata.youtube.com/feeds/api/standardfeeds/top_rated")
.openStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(path);
traverse(document.getDocumentElement());
}
public static void traverse(Node node) {
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node currentNode = list.item(i);
traverse(currentNode);
}
if (node.getNodeName().equals("yt:duration")) {
Element durationElement = (Element) node;
System.out.println(durationElement.getAttribute("seconds"));
}
}
我总是喜欢56
361
225
265
219
220
259
267
376
205
127
308
249
17
162
220
183
298
172
267
204
209
的递归(如上所述),因为它简化了完整的遍历,从而也提供了灵活性。
如果您想了解更多关于将这些元素组合在一起的信息,您也可以参考我的帖子XmlPullParseFactory#setNamespaceAware
。