首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何解析在某些标记中带有冒号的XML?

如何解析在某些标记中带有冒号的XML?
EN

Stack Overflow用户
提问于 2014-02-14 16:52:18
回答 1查看 2.3K关注 0票数 2

我一直在阅读一些关于XmlPullParser中关于如何解析XML数据的教程。更确切地说,我使用的是来自https://gdata.youtube.com/feeds/api/standardfeeds/top_rated的XML

在这里,我简化了这个提要条目的一部分(我希望在不改变结构的情况下):

代码语言:javascript
运行
复制
<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&amp;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>

我成功地获得了标题和链接:

代码语言:javascript
运行
复制
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);之前添加了其他检查。即:

代码语言:javascript
运行
复制
} else if (name.equalsIgnoreCase("yt:")) {
    Utils.logger("i", "entering yt:", TAG);
    readDuration(parser)
}

我用"yt"修改了"yt",或者更改了"yt:duration,没有结果。

也和

代码语言:javascript
运行
复制
String namespace = parser.getNamespace();

并且用name.equalsIgnoreCase...更改namespace.equalsIgnoreCase...,我没有得到日志条目,所以我甚至没有办法尝试这样的方法:

代码语言:javascript
运行
复制
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;
}

增加“应请求”。我不确定它是否足够有用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-14 17:57:42

XmlPullParser似乎具有识别名称空间的能力,区别在于必须显式地设置它。根据XmlPullParseFactory#setNamespaceAware的文档

指定此工厂生成的解析器将提供对XML命名空间的支持。默认情况下,此值设置为false。

你可能想试试这个选择。

此外,正如我试图用零问题遍历xml的注释中所提到的,下面是打印所有持续时间值的源代码(为了让您知道,这将作为一个Java程序运行,而不是在ADT中运行):

代码语言:javascript
运行
复制
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"));
        }

    }

我得到的输出:

代码语言:javascript
运行
复制
56
361
225
265
219
220
259
267
376
205
127
308
249
17
162
220
183
298
172
267
204
209

我总是喜欢使用DOM的递归(如上面所示),因为它简化了整个遍历,从而也提供了灵活性。

如果您想了解有关将这些元素组合在一起的更多信息,也可以参考我的文章here

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21785054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档