2011-05-12 13 views
6

He intentado envolver un conjunto de clases basadas en Simple XML (Java Serializer) alrededor de una fuente RSS. La alimentación de la muestra esXml simple - Elemento declarado error dos veces

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

El error que estoy recibiendo mientras se ejecuta el código es

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

Y el error es bastante justo porque el nombre de elemento particular se produce dos veces en el xml pero de diferentes maneras.

El primer elemento de enlace está aquí

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

Su directamente bajo la etiqueta de canal. Y luego el siguiente código de enlace es de nuevo bajo el canal en el siguiente formato

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

En la clase Channel.java no puedo tener dos variables con el mismo nombre de enlace. He intentado cambiar un nombre de variable a BLOGLINK y trató de dar nombre en la anotación de elementos y Eclipse me dio este error

Change was 

@Element("name=link") 


Result is 

The attribute value is undefined for the annotation Element 

sé que estoy perdiendo algo aquí, pero no puedo poner mi dedo en la llaga. Le agradecería cualquier ayuda en esto.

ACTUALIZACIÓN

Clase Canal

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

public atomlink getAtomLink() { 
    return atomlink; 
} 

Enlace de clase

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

}

he cambiado los nombres de las clases y sin embargo, todavía señala el mismo error.

+0

fue esta vez resueltos? Estoy tratando de mapear las clases de RSS para simple-xml en este momento. Sería bueno si pudieras compartir. –

+1

No, no pude. Envió un correo electrónico a la lista de correo y no recibió una respuesta. De acuerdo con los documentos, el espacio de nombres debería ser el truco, pero no lo fue para mí. Como el tiempo era una limitación para mí, implementé mi propia envoltura rss personalizada con dom xml. – vikramjb

Respuesta

1

Estos son dos elementos diferentes. Difieren por espacio de nombres. Vea cómo puede mapear espacios de nombres (si son compatibles con ese Simple XML).

Uh, que se encuentra en el documento:

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; 

y así sucesivamente.

+1

Lo hice y recibo el mismo error "Enlace de elemento 'declarado dos veces en la línea 24". He agregado las modificaciones de mi código en mi publicación original. Gracias por la respuesta, lo aprecio. – vikramjb

+0

(Actualizado mi ejemplo para mostrar cómo se vería). –

+0

Además, no debe proporcionar el prefijo, ya que puede diferir por mensaje; solo el espacio de nombres es relevante. –

0

La anotación que ha indicado no está formateada correctamente.

Debe ser

@Element(name="link") 

Si una anotación tiene una sola propiedad denominada valor, se puede asignar sin especificar la clave. Pero en este caso, la propiedad que está intentando establecer es 'nombre' que tiene un valor de tipo String.

El problema de la pregunta es que toda la asignación de 'nombre' estaba entre paréntesis, por lo tanto, estaba tratando de establecer 'valor' para ser "nombre = enlace", por lo que estaba explotando, porque el La anotación @Element no especifica una propiedad de valor.

+0

Eso fue un error tipográfico de mi parte. Sin embargo, cambié y me dio un error diferente. Gracias por la respuesta, lo aprecio. – vikramjb

0

que tienen el mismo problema con el análisis del XML contenido:

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

mi código es:

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

El error con esto es:

org.simpleframework.xml.core .PersistenceException: Anotación duplicada del nombre 'rating' en el campo 'ratingLike' public com.devicefms.android.boardgamesreview.beans.VideoXML $ VideoEntry $ LikeRating com.devicefms.android.boardgamesreview.b eans.VideoXML $ VideoEntry.ratingLike en org.simpleframework.xml.core.StructureBuilder.process (StructureBuilder.java:258)

0

Esto no es una solución per se, pero yo era capaz de solucionar este problema por reemplazando las 2 entradas @Element por < atom: link/> y < link/> en mi clase con una sola @ElementList, y creando un objeto que satisfaga ambos tipos de enlaces. Algo como esto:

@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

En segundo lugar, funciona, esperando a que se corrija el error. –

0

¿Se ha solucionado esto? Además de la respuesta de Mark (de usar una colección) ¿hay una forma adecuada de hacer esto? ¿Cómo podríamos protegernos de que otros campos que no se transformaron en colecciones se conviertan en colecciones?

BTW Estoy trabajando con fuentes RSS.

1

Debido a que el elemento de link aparece dos veces (aunque tienen distintos namespace), es necesario contar link aparte, sopló es toda mi respuesta:

1) Rss frijol

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 método

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