解析XML源码时出现“元素已被使用”的错误

19
我正在尝试在Android中使用SimpleXML解析XML订阅源:http://backend.deviantart.com/rss.xml?type=deviation&q=by%3Aspyed+sort%3Atime+meta%3Aall 这里是示例:
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        <title>DeviantArt: spyed's</title>
        <link>http://www.deviantart.com/?order=5&amp;q=by%3Aspyed</link>
        <description>DeviantArt RSS for sort:time by:spyed</description>
        <language>en-us</language>
        <copyright>Copyright 2015, DeviantArt.com</copyright>
        <pubDate>Thu, 20 Aug 2015 07:45:31 PDT</pubDate>
        <generator>DeviantArt.com</generator>
        <docs>http://blogs.law.harvard.edu/tech/rss</docs>
        <atom:icon>http://st.deviantart.net/minish/touch-icons/android-192.png</atom:icon>
        <atom:link type="application/rss+xml" rel="self" href="http://backend.deviantart.com/rss.xml?q=sort%3Atime+by%3Aspyed&amp;type=deviation" />
        <atom:link rel="next" href="http://backend.deviantart.com/rss.xml?q=sort%3Atime+by%3Aspyed&amp;type=deviation&amp;offset=60" />
        <item>
            <title>Happy 15th Birthday!</title>
            <link>http://spyed.deviantart.com/journal/Happy-15th-Birthday-552416478</link>
            <guid isPermaLink="true">http://spyed.deviantart.com/journal/Happy-15th-Birthday-552416478</guid>
            <pubDate>Sun, 09 Aug 2015 01:41:54 PDT</pubDate>
            <media:title type="plain">Happy 15th Birthday!</media:title>
            <media:keywords />
            <media:rating>nonadult</media:rating>
            <media:category label="Personal">journals/personal</media:category>
            <media:credit role="author" scheme="urn:ebu">spyed</media:credit>
            <media:credit role="author" scheme="urn:ebu">http://a.deviantart.net/avatars/s/p/spyed.gif</media:credit>
            <media:copyright url="http://spyed.deviantart.com">Copyright 2015 spyed</media:copyright>
            <media:description type="html" />
            <media:content url="http://spyed.deviantart.com/journal/Happy-15th-Birthday-552416478" medium="document" />
            <media:text type="html">In April I wrote a post reflecting on my 15 years at DeviantArt, since the project began in April of 2000 and was launched to the public on August 7th. I went back and re-read what I wrote, and wow, speaking of audacious I'm pretty hardcore in this post. I write from my heart sometimes and then I hit post and that's that. So for our official 15th Birthday I wanted to re-share a link to that post:&lt;br /&gt;&lt;br /&gt;And then today, I wrote this reflection for you as a toast &amp;amp; thanks for all the llamas:&lt;br /&gt;&lt;br /&gt;Happy 15th Birthday DeviantArt! We are evolving, and soon we will be able to share exactly how you can be a part of our transformation, ensuring that the De</media:text>
            <description />
        </item>
        <item>
            <title>The Floor is Open</title>
            <link>http://spyed.deviantart.com/journal/The-Floor-is-Open-548845475</link>
            <guid isPermaLink="true">http://spyed.deviantart.com/journal/The-Floor-is-Open-548845475</guid>
            <pubDate>Sat, 25 Jul 2015 11:38:46 PDT</pubDate>
            <media:title type="plain">The Floor is Open</media:title>
            <media:keywords />
            <media:rating>nonadult</media:rating>
            <media:category label="Personal">journals/personal</media:category>
            <media:credit role="author" scheme="urn:ebu">spyed</media:credit>
            <media:credit role="author" scheme="urn:ebu">http://a.deviantart.net/avatars/s/p/spyed.gif</media:credit>
            <media:copyright url="http://spyed.deviantart.com">Copyright 2015 spyed</media:copyright>
            <media:description type="html" />
            <media:content url="http://spyed.deviantart.com/journal/The-Floor-is-Open-548845475" medium="document" />
            <media:text type="html">Happy Saturday! I'm hanging out at home, so I thought I'd have an open conversation. Post anything, I'll reply. It's about 11:30am, I'll be in front of this thing for two hours before I go to my god daughters 7th birthday party! Yay!&lt;br /&gt;&lt;br /&gt;If you're wondering what we're up to, check out the DeviantArt Timeline ( http://www.deviantart.com/timeline/ ) -- It might compel you to ask some questions. Or, if there's anything you've been wondering about, ask!&lt;br /&gt;&lt;br /&gt;Here's some food for thought to get you started about the overall state of DeviantArt:&lt;br /&gt;&lt;br /&gt;Our team focuses on two things that matter most to us, the first is our mission to Entertain, Inspire &amp;amp; Em</media:text>
            <description />
        </item>
        ... etc ....

但是我遇到了以下错误:
08-13 15:55:38.529: W/System.err(1437): org.simpleframework.xml.core.PersistenceException: Element 'title' is already used with @org.simpleframework.xml.Element(data=false, name=title, required=false, type=void) on field 'title' public java.lang.String com.example.feedreader.SimpleRss$Channel$RssItem.title at line 1

我注意到有两个不同级别的title标签,但我不确定如何在代码中区分它们。
以下是我的代码:
@Root(name = "rss", strict = false)
public class SimpleRss implements FeedRoot {

    @Root(name = "channel")
    public static class Channel {

        @Element(name = "title", required = false)
        public String title = "";

        @Attribute(name = "href", required = false)
        @ElementList(entry = "link", inline = true, required = false)
        private List<String> links;

        @Element(name = "description", required = false)
        @Namespace(prefix = "")
        public String description = "";

        @Element(name = "pubDate", required = false)
        public String pubDate = "";

        @Element(name = "event_link", required = false)
        public String event_link = "";

        @Root(name = "item")
        public static class RssItem implements SimpleFeedItem {

            public String parent = "";
            public String feedUrl = null;
            public Date date = null;

            @Element(name = "title", required = false)
            public String title = "";

            @Element(name = "link", required = false)
            public String link = "";

            @Element(name = "event_link", required = false)
            public String event_link = "";

            @Element(name = "description", required = false)
            public String description = "";

            @Element(name = "pubDate", required = false)
            public String pubDate = "";

            @Path("enclosure")
            @Attribute(name = "url", required = false)
            public String enclosureUrl = "";

            @Path("enclosure")
            @Attribute(name = "type", required = false)
            public String enclosureType = "";

            @Override
            public String getTitle() {
                return title;
            }

            @Override
            public String getDescription() {
                return description;
            }

            @Override
            public String getLink() {
                return link;
            }

            @Override
            public String getEventLink() {
                return event_link;
            }

            @Override
            public String getAdditional() {
                return parent;
            }

            @Override
            public String getPubDate() {
                return pubDate;
            }

            @Override
            public String getFeedUrl() {
                return feedUrl;
            }

            @Override
            public void setFeedUrl(String url) {
                feedUrl = url;
            }

            @Override
            public void setDate(Date date) {
                this.date = date;
            }

            @Override
            public Date getDate() {
                return date;
            }

            @Override
            public String getPictureUrl() {
                if (DataUtils.isEmpty(enclosureType)) {
                    return null;
                } else if (SimpleFeedItem.SupportedFeedImageTypes
                        .contains(enclosureType.toLowerCase(Locale.ENGLISH))) {
                    return enclosureUrl;
                } else {
                    return null;
                }
            }

        }

        @ElementList(inline = true, required = false)
        public List<RssItem> rssItems = J.newArrayList();

    }

    @Element(name = "channel")
    public Channel channel;

    @Override
    public List<SimpleFeedItem> getItems() {
        List<SimpleFeedItem> items = J.newArrayList();

        if (channel != null && channel.rssItems != null) {
            for (RssItem item : channel.rssItems) {
                String title = channel.title;
                if (title == null) {
                    title = "";
                }
                item.parent = title.intern();
                items.add(item);
            }
        }
        return items;
    }

    @Override
    public String getTitle() {
        if (channel == null) {
            return "";
        } else {
            return channel.title;
        }
    }

}

我已经尝试将其注释掉

@Element(name = "title", required = false)
public String title = "";

Channel类中我得到了相同的错误。 而且,如果我只是重命名它也一样。
然而,如果我在RssItem类中做同样的事情,它将起作用,但我无法获取项目的标题。
谢谢!

你尝试过将其中一个“title”标签更改一下,看看是否解决了问题吗? - Hughzi
嗨@Hughzi,我刚刚在原帖中添加了一个回答来回应你的问题。谢谢! - zundi
这个问题在这里已经有了几乎相同的答案:http://stackoverflow.com/questions/18023830/simplexml-element-link-is-already-used 希望这可以帮到你... - Shahid Farooq
3个回答

21

这个修复了问题:

移除这个:

@Element(name = "title", required = false)

替换为:

//inside the inner class RssItem
@Path("title")
@Text(required=false)
public String title = "";

对于任何其他引发异常的字段,都应该重复此操作。


1
哦我的天,谢谢你!我一百万年也不会使用那个组合。 - ZaBlanc
1
我有相同的XML结构,但我得到了元素“item”已经被使用的错误。请问如何解决这个问题?希望能得到帮助。 - bhaskar
@bhaskar 我同意你的观点。这个解决方案现在不起作用。如果你找到其他帮助,请告诉我。 - undefined

0

似乎使用

@Element(name = "title", required = false, inLine=true)
public String title = "";

将解决您的问题,如此处所示。

6
不起作用。inline属性只适用于ElementList,而不适用于Element。 - zundi

0
你的XML文件中有两个title元素。第一个title元素在channel标签中,另一个title元素在item标签中。因此,你应该指定解析器这些标题的路径是不同的。请按照以下方式进行编辑:
@Element(name = "title", required = false)
public String title = "";

添加路径注释:
@Element(name = "title", required = false)
@Path('rss/channel')
public String title = "";

channel标签中,你指定了title作为你的路径。另一个title与你不同 :)

我也试过了。但是还是不行! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接