Простой Xml - элемент объявлен дважды ошибка - PullRequest
6 голосов
/ 12 мая 2011

Я пытался обернуть набор классов на основе Simple XML (Java Serializer) вокруг RSS-канала. Подача образца составляет

<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
    <title>Coding Horror</title>
    <link>http://www.codinghorror.com/blog/</link>
    <description>programming and human factors - Jeff Atwood</description>
    <language>en-us</language>

    <lastBuildDate>Wed, 04 May 2011 20:34:18 -0700</lastBuildDate>
    <pubDate>Wed, 04 May 2011 20:34:18 -0700</pubDate>
    <generator>http://www.typepad.com/</generator>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>

    <image>
        <title>Coding Horror</title>
        <url>http://www.codinghorror.com/blog/images/coding-horror-official-logo-small.png</url>
        <width>100</width>
        <height>91</height>
        <description>Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.</description>
        <link>http://www.codinghorror.com/blog/</link>
    </image>

    <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />   
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/codinghorror" />        

</channel>
 </rss>

Ошибка при запуске кода:

org.simpleframework.xml.core.PersistenceException: Element 'link' declared twice at line 24

И ошибка достаточно справедлива, потому что имя конкретного элемента встречается дважды в xml, но по-разному.

Первый элемент ссылки здесь

<link>http://www.codinghorror.com/blog/</link>

Прямо под тегом Channel. И тогда следующий тег ссылки снова находится под Каналом в следующем формате

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/codinghorror" />

В классе Channel.java у меня не может быть двух переменных с одинаковыми именами. Я попытался изменить имя переменной на blogLink и попытался дать имя в аннотации элемента, и Eclipse дал мне эту ошибку

 Change was

@Element("name=link")


Result is

The attribute value is undefined for the annotation Element

Я знаю, что я что-то здесь упускаю, но я не могу указать на это. Буду признателен за любую помощь в этом.

UPDATE

Класс канала

@Element(name="link")
@Namespace(reference="http://www.w3.org/2005/Atom",prefix="atom")
private atomlink atomlink;

public atomlink getAtomLink() {
    return atomlink;
}

Ссылка класса

   import org.simpleframework.xml.Attribute;
   import org.simpleframework.xml.Namespace;
   import org.simpleframework.xml.Root;

  @Root(name="link")
  @Namespace(reference="http://www.w3.org/2005/Atom",prefix="atom10")
  public class atomlink {

@Attribute 
private String rel;

public String getRel() {
    return rel;
}

}

Я изменил имена классов, и все же он указывает на ту же ошибку.

Ответы [ 6 ]

1 голос
/ 20 марта 2017

Поскольку элемент link появляется дважды (хотя они имеют различное пространство имен), вы должны сказать link отдельно, весь мой ответ взорван:

1) Rss боб

package com.example.xyzreader.data.bean;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Text;

import java.util.List;

/**
 * @author zmingchun
 * @version 1.0.0 (2017/3/20)
 */
@NamespaceList({
        @Namespace(prefix = "dc", reference = "http://purl.org/dc/elements/1.1/"),
        @Namespace(prefix = "atom", reference = "http://www.w3.org/2005/Atom"),
        @Namespace(prefix = "xhtml", reference = "http://www.w3.org/1999/xhtml"),
        @Namespace(prefix = "atom10", reference = "http://www.w3.org/2005/Atom"),
})
@Root(name = "rss" , strict = false)
public class Rss {
    @Element(name = "channel")
    public ChannelBean channel;
    @Attribute
    public String version;

    @Override
    public String toString() {
        return "Rss{" +
                "channel=" + channel +
                ", version='" + version + '\'' +
                '}';
    }

    @Root(name = "channel", strict = false)
    public static class ChannelBean {
        @Element
        public String title;
        @ElementList(entry = "link", inline = true, required = false)
        public List<Link> links;
        @Element
        public String description;
        @Element
        public String language;
        @Element
        public String lastBuildDate;
        @Element
        public String pubDate;
        @Element
        public String generator;
        @Element
        public String docs;
        @Element
        public ImageBean image;
        @Element
        public MetaBean meta;

        @Override
        public String toString() {
            return "ChannelBean{" +
                    "title='" + title + '\'' +
                    ", links=" + links +
                    ", description='" + description + '\'' +
                    ", language='" + language + '\'' +
                    ", lastBuildDate='" + lastBuildDate + '\'' +
                    ", pubDate='" + pubDate + '\'' +
                    ", generator='" + generator + '\'' +
                    ", docs='" + docs + '\'' +
                    ", image=" + image +
                    ", meta=" + meta +
                    '}';
        }

        /**
         * link bean
         */
        static class Link {
            @Attribute(required = false)
            public String href;

            @Attribute(required = false)
            public String rel;

            @Attribute(name = "type", required = false)
            public String contentType;

            @Text(required = false)
            public String link;

            @Override
            public String toString() {
                return "Link{" +
                        "href='" + href + '\'' +
                        ", rel='" + rel + '\'' +
                        ", contentType='" + contentType + '\'' +
                        ", link='" + link + '\'' +
                        '}';
            }
        }

        @Root(name = "image")
        public static class ImageBean {
            @Element
            public String title;
            @Element
            public String url;
            @Element
            public String width;
            @Element
            public String height;
            @Element
            public String description;
            @Element
            public String link;

            @Override
            public String toString() {
                return "ImageBean{" +
                        "title='" + title + '\'' +
                        ", url='" + url + '\'' +
                        ", width='" + width + '\'' +
                        ", height='" + height + '\'' +
                        ", description='" + description + '\'' +
                        ", link='" + link + '\'' +
                        '}';
            }
        }

        @Root(name = "meta")
        public static class MetaBean {
            @Attribute(required = false)
            public String name;

            @Attribute(required = false)
            public String content;

            @Override
            public String toString() {
                return "MetaBean{" +
                        "name='" + name + '\'' +
                        ", content='" + content + '\'' +
                        '}';
            }
        }
    }
}

2) TestSimpleXmlConvert метод

package com.example.xyzreader.manager;

import android.util.Log;

import com.example.xyzreader.data.bean.Rss;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.convert.AnnotationStrategy;
import org.simpleframework.xml.core.Persister;
import org.simpleframework.xml.strategy.Strategy;

/**
 * @author zmingchun
 * @version 1.0.0 (2017/3/20)
 */
public class TestSimpleXmlConvert {
    /**
     * test convert by simple-xml-2.7.1
     */
    public static void main(String[] args) {
        Strategy strategy = new AnnotationStrategy();
        Serializer serializer = new Persister(strategy);
        try {
            Rss tRss = serializer.read(Rss.class, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                    "<rss  xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:atom=\"http://www.w3.org/2005/Atom\" version=\"2.0\">\n" +
                    "<channel>\n" +
                    "    <title>Coding Horror</title>\n" +
                    "    <link>http://www.codinghorror.com/blog/</link>\n" +
                    "    <description>programming and human factors - Jeff Atwood</description>\n" +
                    "    <language>en-us</language>\n" +
                    "\n" +
                    "    <lastBuildDate>Wed, 04 May 2011 20:34:18 -0700</lastBuildDate>\n" +
                    "    <pubDate>Wed, 04 May 2011 20:34:18 -0700</pubDate>\n" +
                    "    <generator>http://www.typepad.com/</generator>\n" +
                    "    <docs>http://blogs.law.harvard.edu/tech/rss</docs>\n" +
                    "\n" +
                    "    <image>\n" +
                    "        <title>Coding Horror</title>\n" +
                    "        <url>http://www.codinghorror.com/blog/images/coding-horror-official-logo-small.png</url>\n" +
                    "        <width>100</width>\n" +
                    "        <height>91</height>\n" +
                    "        <description>Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.</description>\n" +
                    "        <link>http://www.codinghorror.com/blog/</link>\n" +
                    "    </image>\n" +
                    "\n" +
                    "    <xhtml:meta xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" name=\"robots\" content=\"noindex\" />   \n" +
                    "    <atom10:link xmlns:atom10=\"http://www.w3.org/2005/Atom\" rel=\"self\" type=\"application/rss+xml\" href=\"http://feeds.feedburner.com/codinghorror\" />        \n" +
                    "\n" +
                    "</channel>\n" +
                    " </rss>");
            Log.e(TestSimpleXmlConvert.class.getSimpleName(), "Convert result:"+ tRss.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
1 голос
/ 12 мая 2011

Это два разных элемента.Они различаются по пространству имен.Посмотрите, как можно сопоставить пространства имен (если они вообще поддерживаются этим простым XML).

Э-э, нашел его в документе:

http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#namesoace

@Element(name="link")
private Link link;

@Element(name="link")
@Namespace(reference="http://www.w3.org/2005/Atom")
private AtomLink atomLink;

и т. д.

0 голосов
/ 19 апреля 2013

Это было решено?Помимо ответа Марка (об использовании коллекции), есть ли правильный способ сделать это?Как бы мы защитились от того, чтобы другие поля, которые не были превращены в коллекцию, стали коллекциями?

Кстати, я работаю с RSS-лентами.

0 голосов
/ 26 октября 2012

Это не само по себе исправление, но я смог обойти эту проблему, заменив 2 записи @Element для и в моем классе одним @ElementList, и создание объекта, который бы удовлетворял обоим типам ссылок. Примерно так:

@NamespaceList({
   @Namespace(reference="http://www.w3.org/2005/Atom",prefix="atom")
})
public class Channel {

...

@ElementList(entry="link",inline=true,required=false)
public List<Link> links

...

}

public class Link {
   @Attribute(required=false)
    public String href;

    @Attribute(required=false)
    public String rel;

    @Attribute(name="type",required=false)
    public String contentType;

    @Text(required=false)
    public String link;
}
0 голосов
/ 04 октября 2012

У меня та же проблема при разборе XML с содержимым:

<gd:rating average='4.9304347' max='5' min='1' numRaters='230' rel='http://schemas.google.com/g/2005#overall'/><yt:statistics favoriteCount='0' viewCount='43378'/><yt:rating numDislikes='4' numLikes='226'/>

мой код:

        @Element(name="rating", required=false) 
    @Namespace(prefix="gd", reference="http://schemas.google.com/g/2005")
    public Rating rating;

    @Element(name="rating")     
    @Namespace(prefix="yt", reference="http://gdata.youtube.com/schemas/2007")
    public LikeRating ratingLike;

Ошибка с этим:

org.simpleframework.xml.core.PersistenceException: Дублирующая аннотация имени 'rating' в поле 'ratingLike' public com.devicefms.android.boardgamesreview.beans.VideoXML $ VideoEntry $ LikeRating com.devicefms.android.boardgamesreview.beans.VideoXML $ VideoEntry.ratingLike at org.simpleframework.xml.core.StructureBuilder.process (StructureBuilder.java:258)

0 голосов
/ 12 мая 2011

Указанная вами аннотация неправильно отформатирована.

Это должно быть

@Element(name="link")

Если у аннотации есть одно свойство с именем value, его можно назначить без указания ключа.Но в этом случае вы пытаетесь установить свойство 'name', которое имеет значение типа String.

Вопрос в том, что все присвоение 'name' заключено в круглые скобки, поэтомуон пытался установить для «value» значение «name = link», и поэтому он взрывался, потому что аннотация @Element не указывает свойство value.

...