1

I try to parse XML like this:

fun main() {
val kotlinXmlMapper = XmlMapper(JacksonXmlModule().apply {
    setDefaultUseWrapper(false)
}).registerKotlinModule()
        .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

val value: Feed = kotlinXmlMapper.readValue("""
    <feed xmlns="http://www.w3.org/2005/Atom">
      <entry>
        <id>Test-1</id>
        <title>Test</title>
        <summary type="html">Test</summary>
      </entry>
      <entry>
        <id>Test-2</id>
        <title>Test2</title>
        <summary type="html">Test2</summary>
      </entry>
    </feed>
""".trimIndent(), Feed::class.java)
println(value)}

My data classes looks like this:

@JacksonXmlRootElement(localName="feed")
data class Feed(
        @JacksonXmlElementWrapper(localName="entry")
        @JsonProperty("entry")
        val entry: List<Entry>)

@JacksonXmlRootElement(localName="entry")
data class Entry(val id: String, val title: String, val summary: String)

I thought I annotate the list element with JacksonXmlElementWrapper and then it should work. but unfortunately not:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `service.Entry` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Test-1')
 at [Source: (StringReader); line: 3, column: 15] (through reference chain: service.Feed["entry"]->java.util.ArrayList[0])

Have anybody an idea/suggestions?

Thanks in advance.

Manu Zi
  • 2,300
  • 6
  • 33
  • 67
  • Try to parse it without `Feed` class. Just as a list: `List`. Take a look on this `Java` example: [Parsing XML to Java Object Node](https://stackoverflow.com/questions/62646439/parsing-xml-to-java-object-node/62647544#62647544) – Michał Ziober Jul 04 '20 at 23:52
  • @MichałZiober Awesome! Now it works! Can you add an answer with some explanation why it's now working? Then I can accept the answer – Manu Zi Jul 05 '20 at 18:12

1 Answers1

1

In XML, by default list items are wrapped by an extra node. This node does not represent extra class in POJO model, so, we can skip it. You need to represent in POJO model only item node and specify to Jackson that you want to read payload as a list of these nodes:

val genres = kotlinXmlMapper.readValue<List<Entry>>(json)

See also:

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146