Reputation: 325
I´m using the Jackson XmlMapper to map and xml into a POJO but I have the following problem:
My XML looks like this (not the original one, only an example):
<?xml version="1.0" encoding="UTF-8"?>
<result>
<pojo>
<name>test</name>
</pojo>
</result>
The problem is, I don´t want to parse the "result" object. I wan´t to parse the pojo as an own object. Can I do this with XmlMapper?
thank you!
Artur
Upvotes: 0
Views: 1952
Reputation: 1514
Just to add more on this (In order yo make this generic), I had a scenario where I had to extract a specific element and map that to java object, in this case we can put a conditional check whenever that tag encountered get that out and map the same.
I have added DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
to ignore fields which is not needed, in case our pojo has less fields to map than what we are getting from end source.
Below is the tested code -
while (xmlStreamReader.hasNext()) {
xmlStreamReader.next();
if (xmlStreamReader.nextTag() == XMLEvent.START_ELEMENT) {
QName name = xmlStreamReader.getName();
if (("spcific_name").equalsIgnoreCase(name.getLocalPart())) {
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
result = objectMapper.readValue(xmlStreamReader, Pojo.class);
break;
}
}
}
Upvotes: 0
Reputation: 131496
You can do it but you must write some boiler plate code.
You must create an instance of XMLStreamReader
to be able to do customized reading of your xml input. The next()
method allows to go to the next parsing event of the reader. It's rather a tricky method() related to the internal rules of the reader. So read the documentation to understands particularities :
From the Javadoc:
int javax.xml.stream.XMLStreamReader.next() throws XMLStreamException
Get next parsing event - a processor may return all contiguous character data in a single chunk, or it may split it into several chunks. If the property javax.xml.stream.isCoalescing is set to true element content must be coalesced and only one CHARACTERS event must be returned for contiguous element content or CDATA Sections. By default entity references must be expanded and reported transparently to the application. An exception will be thrown if an entity reference cannot be expanded. If element content is empty (i.e. content is "") then no CHARACTERS event will be reported.
Given the following XML: content textHello</greeting>]]>other content The behavior of calling next() when being on foo will be: 1- the comment (COMMENT) 2- then the characters section (CHARACTERS) 3- then the CDATA section (another CHARACTERS) 4- then the next characters section (another CHARACTERS) 5- then the END_ELEMENT
NOTE: empty element (such as ) will be reported with two separate events: START_ELEMENT, END_ELEMENT - This preserves parsing equivalency of empty element to . This method will throw an IllegalStateException if it is called after hasNext() returns false.
Returns: the integer code corresponding to the current parse event
Let me illustrate the way to proceed with an unit test :
@Test
public void mapXmlToPojo() throws Exception {
XMLInputFactory factory = XMLInputFactory2.newFactory();
InputStream inputFile = MapXmlToPojo.class.getResourceAsStream("pojo.xml");
XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(inputFile);
XmlMapper xmlMapper = new XmlMapper();
xmlStreamReader.next();
xmlStreamReader.next();
Pojo pojo = xmlMapper.readValue(xmlStreamReader, Pojo.class);
Assert.assertEquals("test", pojo.getName());
}
Upvotes: 2