0

I'm trying to simply unmarshal an XML file as below:

<?xml version="1.0" encoding = "UTF-8" ?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <products>
        <product>
            <facet type="string" elementType="string" name="Weight (g)"><![CDATA[210]]></facet>
        </product>
    </products>
</feed>

I've got this classes:

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement(name = "feed")
@XmlAccessorType(XmlAccessType.FIELD)
public class Feed {
    private Products products;
}

Subclass Products:

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Products {
    private List<Product> products;
}

Subclass Product:

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Product {

    @XmlElement(name = "facet")
    private List<Facet> facet;
}

And finally Facet:

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Facet {
    @XmlElement(name = "name")
    private String name;

    @XmlElement(name = "type")
    private String type;

    @XmlElement(name = "elementType")
    private String elementType;

    private String content;
}

The camel route I've written to unmarshall is as below:

@Component
public class XMLSplitterRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        from("file:src/main/resources/files/xml").routeId("xmlUmarshaller")
            .log("body: ${body}")
            .unmarshal().jacksonXml(Products.class)
                .log("The unmarshalled object is ${body}")
            .marshal().json()
            .to("activemq:json-marshal-queue");
    }
}

But I keep getting the error below:

com.fasterxml.jackson.databind.JsonMappingException: Unexpected non-whitespace text ('210' in Array context: should not occur (or should be handled)
 at [Source: (BufferedInputStream); line: 29, column: 96] (through reference chain: com.sammy.model.Products["products"]->java.util.ArrayList[0]->com.sammy.model.Product["facet"])

and

Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected non-whitespace text ('210' in Array context: should not occur (or should be handled)
 at [Source: (BufferedInputStream); line: 29, column: 96]

This means, it seems not to know what to do with the value within the cdata of the XML file! I've looked everywhere but not seen any potential solution. Please, help!!!

Sammy65
  • 627
  • 2
  • 12
  • 28
  • Could you please add the class `Products`? – Nicolas Filotto Mar 29 '22 at 14:46
  • 1
    @NicolasFilotto, didn't realize I left it out. Done so now. Thanks! – Sammy65 Mar 29 '22 at 15:01
  • 1
    It looks like there are several problems, first your mapping that doesn't seem to be correct for example in `Facet` we should have only `XmlAttribute`. Moreover the root element is `feed` so you are supposed to configure Jackson XML with `jacksonXml(Feed.class)`. But even with a mapping that works with JAXB, I could not make it work with Jackson XML even when used directly without Camel. I'll try to investigate it more a more asap. – Nicolas Filotto Mar 30 '22 at 07:48
  • @NicolasFilotto, thanks for your assistance! Would it be better to use DataFormat instead of JacksonXML? I don't have to use this actually. – Sammy65 Mar 30 '22 at 09:35
  • 1
    You should use the JAXB data format instead https://camel.apache.org/components/3.14.x/dataformats/jaxb-dataformat.html – Nicolas Filotto Mar 30 '22 at 09:39
  • 1
    Though you still have to fix your mapping, I can assist you on that if needed – Nicolas Filotto Mar 30 '22 at 09:41
  • I just tried the jaxb option which gave me this error. `Caused by: javax.xml.bind.JAXBException: "com.sammy.model.Feed" doesnt contain ObjectFactory.class or jaxb.index` I've been able to generate the classes by converting the xml to xsd then to POJO using xjc. I reverted to JacksonXML and tried this here which didn't work either. https://stackoverflow.com/questions/29502814/deserializing-cdata-with-jacksonxml-unrecognizedpropertyexception – Sammy65 Mar 30 '22 at 11:01

1 Answers1

0

From the nice suggestiongs of Nicolas Filotto, I fixed my mappings by first converting my XML to XSD then generated the POJO's using xjc. For Camel unmarshal process, I changed it from jacksonXML to use Jaxb converter.

@Component
public class XMLSplitterRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        DataFormat jaxb = new JaxbDataFormat("com.sammy.model");

        from("file:src/main/resources/files/xml").routeId("xmlSplitter")
            .log("body: ${body}")
            .unmarshal(jaxb)
                .log("The unmarshalled object is ${body}")
    }
}

This now works like a charm!!!

Sammy65
  • 627
  • 2
  • 12
  • 28
  • I've got a little issue using this logic with a large file of 168MB! I get this message from Camel. `Created XMLInputFactory: com.sun.xml.internal.stream.XMLInputFactoryImpl@225ad85f. DOMSource/DOMResult may have issues with com.sun.xml.internal.stream.XMLInputFactoryImpl@225ad85f. We suggest using Woodstox.` Any suggestions @Nicolas Filotto? (-; – Sammy65 Mar 30 '22 at 16:35
  • 1
    Please create a new question as it is not the same problem. – Nicolas Filotto Mar 30 '22 at 17:08