-1

I am using Jackson to work with my XML data, based on this Baeldung tutorial.

I have the following class to model some XML:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class SimpleBean {

    private int x = 1;
    private int y = 2;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public SimpleBean fromString(String xml) throws JsonProcessingException {
        XmlMapper xmlMapper = new XmlMapper();
        return xmlMapper.readValue(xml, SimpleBean.class);
    }
}

I have the following test that passes:

@Test
void testFromString() throws Exception {
    SimpleBean bean = new SimpleBean();
    String xml = "<SimpleBean><x>11</x><y>22</y></SimpleBean>";
    SimpleBean beanParsed = bean.fromString(xml);
    Assertions.assertEquals(11, beanParsed.getX());
}

What I would like to do is something like this:

@Test
void testFromStringWanted() throws Exception {
    SimpleBean bean = new SimpleBean();
    String xml = "<SimpleBean><x>11</x><y>22</y></SimpleBean>";
    bean.fromString(xml);
    Assertions.assertEquals(11, bean.getX());  // FAILS
}

I would like to parse the string into the instance bean that I already have. I do not want to have to create a second beanParsed.

I tried to change my fromString method to:

public void fromString(String xml) throws JsonProcessingException {
    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.readValue(xml, this.getClass());
}

but that did not work. No errors, it just did not produce the desired results.

Also tried this, but that does not even compile!

public void fromString(String xml) throws JsonProcessingException {
    XmlMapper xmlMapper = new XmlMapper();
    this = xmlMapper.readValue(xml, SimpleBean.class);
}

How can I do this?

4
  • How does it fail? fromString returns a Bean but you do not save/use it. bean.getX() returns a value that has not been set. Commented Mar 7, 2024 at 1:11
  • fromString is a factory method and should be static. Then you invoke it without instantiating a SimpleBean first, because it returns the new SimpleBean. Commented Mar 7, 2024 at 1:32
  • For an example of a built-in factory method, look at the reason behind things like Long.parseLong(String...) and many others in the standard library. This is what you want, not a hack to update the bean after creation. Commented Mar 7, 2024 at 1:39
  • @JimGarrison Thank you for the suggestion. In my case I will always have one instance of SimpleBean, I just wanted to be able to parse the xml string into the existing one. The answer that Nir gave, below, is exactly what I was looking for. Commented Mar 7, 2024 at 15:51

1 Answer 1

1

Try:

public void fromString(String xml) throws JsonProcessingException {
    XmlMapper xmlMapper = new XmlMapper();
    // Use readerForUpdating() to parse into the existing instance
    xmlMapper.readerForUpdating(this).readValue(xml);
}

Jackson provides a method called readerForUpdating() specifically for parsing data into an existing object.

This method creates a reader that updates an existing object instead of creating a new one.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.