Android Retrofit 2简单XML转换器

时间:2016-06-18 17:38:39

标签: android xml retrofit retrofit2 simple-framework

我正在使用Retrofit 2.1.0 和Retrofit SimpleXML Converter 2.1.0 。我添加了simplexmlconverter来使用addConverterFactory方法改进实例。

XML在

之下
__IOS_UNAVAILABLE

我的改造api客户端相关代码: RetrofitAPIClient

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
   <channel>
      <title>title</title>
      <description></description>
      <language>en-us</language>
      <item>
         <title>text</title>
         <link>text</link>
         <description>text</description>
         <enclosure url="text" length="2043520" type="image/jpeg" />
         <guid isPermaLink="false">text</guid>
         <pubDate>Fri, 17 Jun 2016 11:43 EDT</pubDate>
         <source url="text">text</source>
      </item>
      <item>
         <title>text</title>
         <link>text</link>
         <description>text</description>
         <enclosure url="text" length="1735257" type="image/jpeg" />
         <guid isPermaLink="false">text</guid>
         <pubDate>Thu, 16 Jun 2016 10:17 EDT</pubDate>
         <source url="text"></source>
      </item>
      <item>
         <title>text</title>
         <link>text</link>
         <description>text</description>
         <enclosure url="text" length="3763157" type="image/jpeg" />
         <guid isPermaLink="false">text</guid>
         <pubDate>Wed, 15 Jun 2016 10:02 EDT</pubDate>
         <source url="text">text</source>
      </item>
   </channel>
</rss>

ArticleResponse.java

OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .build();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(client)
        .addConverterFactory(SimpleXmlConverterFactory.create())
        .build();

apiService = retrofit.create(MyService.class);

Article.java

import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

import java.util.List;

@Root(name = "rss")
public class ArticleResponse {

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

    public class Channel {

        @ElementList
        public List<Article> articles;
    }
}

错误是:

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Text;

@Element(name = "item")
public class Article {

    @Element(name = "title")
    private String title;

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

    @Element(name = "description")
    private String description;

    @Element(name = "enclosure")
    private Enclosure enclosure;

    @Element(name = "guid")
    private String guid;

    @Element(name = "pubDate")
    private String pubDate;

    @Element(name = "source")
    private Source source;

    public class Enclosure {

        @Attribute(name = "url")
        private String url;

        @Attribute(name = "length")
        private long length;

        @Attribute(name = "type")
        private String type;
    }

    public class Source {

        @Attribute(name = "url")
        private String url;

        @Text
        private String text;
    }
}

3 个答案:

答案 0 :(得分:3)

尝试strict = false

@Root(name = "rss", strict = false)
public class ArticleResponse {

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

    public class Channel {

        @ElementList
        public List<Article> articles;
    }
}

答案 1 :(得分:2)

面临同样的问题。解决方案是使内部类静态(或者只创建一个新的单个java类)。还为“channel”节点添加“Root”注释。

SELECT P.*,
           distance_in_meters_lat_lng(P.post_latitude, P.post_longitude, :latitude, :longitude) as distance,
           U.user_id,
           U.user_name,
           U.user_lastName,
           U.user_photo,
           LT.time_hour,
           LC.category_name,
           (SELECT COUNT(*) FROM posts_likes PL WHERE PL.post_id = P.post_id) as likes,
           (SELECT COUNT(*) FROM comments C WHERE C.post_id = P.post_id) as comments,
           (SELECT COUNT(*) FROM posts_likes PL2 WHERE PL2.post_id = P.post_id AND PL2.user_id = :user_id) as like_status,
           (SELECT COUNT(*) FROM post_participants PC WHERE PC.post_id = P.post_id) as participants,
           (SELECT COUNT(*) FROM post_participants PC2 WHERE PC2.post_id = P.post_id AND PC2.user_id = :user_id) as participant_status,
           (SELECT user_id FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as winner,
           (SELECT user_name FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as name,
           (SELECT user_lastName FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as lastName,
           (SELECT user_photo FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as photo
    FROM posts P
    INNER JOIN users U USING(user_id)
    LEFT JOIN lot_times LT USING(time_id)
    LEFT JOIN lot_categories LC USING(category_id)
    WHERE P.post_type = 'lot'
    ORDER BY participants DESC, likes DESC, comments DESC
    LIMIT 0,20

与“enclosure”和“source”节点相同 - 制作新文件或制作静态内部类。

@Root(name = "rss", strict = false)
public class ArticleResponse {

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


@Root(name = "channel", strict = false)
static class Channel {

    @ElementList(inline = true, name="item")
    private List<Article> articles;
  }

}

答案 2 :(得分:2)

您看到这个的原因是因为您缺少XML文档中“default”属性的注释。

SimpleXML的默认行为是设置(strict = true),这意味着您需要在文档中注释所有元素和属性,否则它将抛出您正在看到的运行时异常。

因此,对于下面的示例XML:

<response xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XML-Schema-instance" version="1.2">
    <sample_string>Brady</sample_string>
    <sample_integer>12</sample_integer>
</response>

您需要使用(strict = false)标志来忽略“version”属性:

@Root(strict = false)
public class Response {
    @Element(name = "sample_string")
    private String sampleString;

    @Element(name = "sample_integer")
    private Integer sampleInteger;

    public String getSampleString() {
        return sampleString;
    }

    public Integer getSampleInteger() {
        return sampleInteger;
    }
}

或者,注释班级中的“版本”属性:

@Root
public class Response {
    @Attribute(name = "version")
    private String version;

    @Element(name = "sample_string")
    private String sampleString;

    @Element(name = "sample_integer")
    private Integer sampleInteger;

    public String getVersion() {
        return version;
    }

    public String getSampleString() {
        return sampleString;
    }

    public Integer getSampleInteger() {
        return sampleInteger;
    }
}