简单 Xml - 元素声明两次错误

发布于 2024-11-06 20:03:59 字数 3024 浏览 4 评论 0原文

我一直在尝试将一组基于 Simple XML (Java Serializer) 的类包装在 RSS Feed 周围。示例提要是

<?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 标签的正下方。然后下一个链接标记再次位于 Channel 下,格式如下

在 Channel.java 类中,我不能有两个具有相同名称链接的变量。我尝试将变量名称更改为 blogLink 并尝试在元素注释中给出名称,Eclipse 给了我这个错误,

 Change was

@Element("name=link")


Result is

The attribute value is undefined for the annotation Element

我知道我在这里遗漏了一些东西,但我无法指出它。我将不胜感激任何帮助。

UPDATE

Channel Class

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

public atomlink getAtomLink() {
    return atomlink;
}

Link Class

   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;
}

}

我已经更改了类名称,但它仍然指向相同的错误。

I have been trying to wrap a set of classes based on Simple XML (Java Serializer) around a RSS Feed. The sample feed is

<?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>

The error that I am getting while running the code is

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

And the error is fair enough because the particular element name occurs twice in the xml but in different ways.

The first link element is here

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

Its directly under the Channel tag. And then the next link tag is again under Channel in the following format

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

In Channel.java class I cannot have two variables with the same name link. I tried changing a variable name to blogLink and tried giving name in the Element annotation and Eclipse gave me this error

 Change was

@Element("name=link")


Result is

The attribute value is undefined for the annotation Element

I know I am missing something here but I am not able to put my finger on it. I would appreciate any help on this.

UPDATE

Channel Class

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

public atomlink getAtomLink() {
    return atomlink;
}

Link Class

   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;
}

}

I have changed the class names and yet it still points to the same error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

贱贱哒 2024-11-13 20:04:00

这是两个不同的元素。它们因命名空间而异。了解如何映射命名空间(如果该简单 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;

等等。

These are two different elements. They differ by namespace. See how can you map namespaces (if they are supported by that Simple XML at all).

Uh, found it in the doc:

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;

and so on.

痴情换悲伤 2024-11-13 20:04:00

您列出的注释格式不正确。

@Element(name="link")

如果注释有一个名为 value 的属性,则可以在不指定键的情况下对其进行分配 但在本例中,您尝试设置的属性是“name”,其值为 String 类型。

这个问题的问题是“name”的整个赋值都包含在括号中,因此它试图将“value”设置为“name=link”,这就是它爆炸的原因,因为@Element注释不不指定值属性。

The annotation you have listed is not formatted properly.

It should be

@Element(name="link")

If an annotation has a single property named value, it can be assigned without specifying the key. But in this case, the property you are attempting to set is 'name' which has a value of type String.

The issue from the question is that the whole assignment of 'name' was enclosed in parenthesis, thus it was trying to set 'value' to be "name=link", which is why it was blowing up, because the @Element annotation doesn't specify a value property.

Saygoodbye 2024-11-13 20:04:00

我在解析 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: 字段“ ratingLike” public com.devicefms.android 上名称“ rating”的重复注释。 boardgamesreview.beans.VideoXML$VideoEntry$LikeRating com.devicefms.android.boardgamesreview.beans.VideoXML$VideoEntry. ratingLike
在 org.simpleframework.xml.core.StructureBuilder.process(StructureBuilder.java:258)

I have the same problem parsing the xml with content:

<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'/>

my code is:

        @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;

The error with this is:

org.simpleframework.xml.core.PersistenceException: Duplicate annotation of name 'rating' on field '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)

如果没有你 2024-11-13 20:04:00

这本身并不是一个修复,但我可以通过替换的 2 个 @Element 条目来解决这个问题。和<链接/>>在我的类中使用单个 @ElementList,并创建一个满足两种 Link 类型的对象。像这样的东西:

@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;
}

This is not a fix per-se, but I was able to work around this issue by replacing the 2 @Element entries for <atom:link/> and <link/> in my class with a single @ElementList, and creating an object that would satisfy both Link types. Something like this:

@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;
}
你的背包 2024-11-13 20:04:00

这个问题已经解决了吗?除了马克的回应(使用集合)之外,还有正确的方法吗?我们如何防止其他没有变成集合的字段变成集合?

顺便说一句,我正在使用 RSS 提要。

Has this been resolved? Besides Mark's response (of using a collection) is there a proper way of doing this? How would we guard against other fields that weren't turned into collection become collections?

BTW I am working with RSS feeds.

物价感观 2024-11-13 20:03:59

因为 link 元素出现了两次(虽然它们有不同的命名空间),所以你需要区分 link ,我的整个答案如下:

1)Rss bean

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();
        }
    }
}

Because the link element appears twice(though they have different namespace), you need to tell link apart, blew is my whole answer:

1)Rss bean

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 method

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();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文