3

I'm struggling to understanding how I can deserialize the following response from an RSS feed. I need the text blah blah blah etc as well as the embedded image source http://host/path/to/picture.jpg.

<description>blah blah blah blah br /&gt;
<![CDATA[<img src=http://host/path/to/picture.jpg>]]>&lt;br /&gt;
blah blah blah blah&lt;br /&gt;&lt;br /&gt;
</description>

Here's my model class (or rather what I want it to be) - I've shortened it for brevity:

public static class Item {
 ...
 @Element(name="description", required=false)
 String descriptionContent;
 String imageLink;
 ...
}

From the docs I know I can set data=true on the @Element attribute but from my reading that works if the entire content of your element is CDATA, not partially.

I'm using doing this on Android using Retrofit and the SimpleXMLConverter but I think that is just by the by.

asked Jul 21, 2016 at 19:26
2
  • Thanks for the downvotes without comment. Helped me a lot! Commented Jul 23, 2016 at 12:14
  • I got the same problem. Do you have any better solution ? Commented Apr 10, 2017 at 10:12

1 Answer 1

3

I figured this out eventually. Hopefully this will help others in the future.

What was needed was a way to interrupt the deserialization process and run some custom code to extract the data. SimpleXML allows you to use many different strategies for serialization / deserialization. I chose one called the Annotation Strategy where by I annotate my POJO model class with the @Convert annotation that points to a converter class.

....
@Element(name="description", required=false)
@Convert(DescriptionConverter.class)
Description description;
...

And here's what the converter looks like:

public class DescriptionConverter implements Converter<RssFeed.Description> {
 @Override
 public RssFeed.Description read(InputNode node) throws Exception {
 final String IMG_SRC_REG_EX = "<img src=([^>]+)>";
 final String HTML_TAG_REG_EX = "</?[^>]+>";
 String nodeText = node.getValue();
 Pattern imageLinkPattern = Pattern.compile(IMG_SRC_REG_EX);
 Matcher matcher = imageLinkPattern.matcher(nodeText);
 String link = null;
 while (matcher.find()) {
 link = matcher.group(1);
 }
 String text = nodeText.replaceFirst(IMG_SRC_REG_EX, "")
 .replaceAll(HTML_TAG_REG_EX, "");
 return new RssFeed.Description(text, link);
 }
 @Override
 public void write(OutputNode node, RssFeed.Description value) throws Exception {
 ...
 }
}

You still need to tell Simple to use a different strategy though otherwise it will ignore the annotation. Given that I am using Retrofit and the SimpleXMLConverter here is what my implemenation looks like:

private static final Retrofit.Builder builder = new Retrofit.Builder()
 .baseUrl(API_BASE_URL)
 .addConverterFactory(SimpleXmlConverterFactory.create(new Persister(new AnnotationStrategy())));
answered Jul 23, 2016 at 12:30
1

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.