Skip to content

Commit

Permalink
Serialize to actual json array/object
Browse files Browse the repository at this point in the history
  • Loading branch information
Croway committed Mar 2, 2024
1 parent daf6dfa commit e763443
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ public class XmlFactoryBuilder extends TSFBuilder<XmlFactory, XmlFactoryBuilder>
*<p>
* Value used for pseudo-property used for returning empty XML tag.
* Defaults to empty String, but may be changed.
*
* In case of deserialization/serialization to JSON via JsonNode
* and _valueForEmptyElement is equals to [] or {}, the JSON will be serialized
* with actual empty json array or object instead of text value ("[]" or "{}")
*/
protected String _valueForEmptyElement = FromXmlParser.DEFAULT_EMPTY_ELEMENT_VALUE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,19 @@ public JsonToken nextToken() throws IOException
// expose "XmlText" as separate property
token = _nextToken();

// Handle JSON object
if (currentValue() == null && _xmlTokens._emptyElement) {
if ("[]".equals(_currText)) {
_nextToken = JsonToken.END_ARRAY;
_parsingContext = _parsingContext.createChildArrayContext(-1, -1);
return (_currToken = JsonToken.START_ARRAY);
} else if ("{}".equals(_currText)) {
_nextToken = JsonToken.END_OBJECT;
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
return (_currToken = JsonToken.START_OBJECT);
}
}

if (token == XmlTokenStream.XML_END_ELEMENT) {
if (_parsingContext.inArray()) {
if (XmlTokenStream._allWs(_currText)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ public class XmlTokenStream

protected final String _valueForEmptyElement;

/**
* true if the current tag is empty
*/
protected boolean _emptyElement;

/**
* Marker flag set if caller wants to "push back" current token so
* that next call to {@link #next()} should simply be given what was
Expand Down Expand Up @@ -190,6 +195,7 @@ public XmlTokenStream(XMLStreamReader xmlReader, ContentReference sourceRef,
_xmlReader = Stax2JacksonReaderAdapter.wrapIfNecessary(xmlReader);
_nameProcessor = nameProcessor;
_valueForEmptyElement = valueForEmptyElement;
_emptyElement = false;
}

/**
Expand Down Expand Up @@ -569,13 +575,15 @@ private final String _collectUntilTag() throws XMLStreamException
{
// 21-Jun-2017, tatu: Whether exposed as `null` or "" is now configurable...
if (_xmlReader.isEmptyElement()) {
_emptyElement = true;
_xmlReader.next();
if (FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL.enabledIn(_formatFeatures)) {
return null;
}
return _valueForEmptyElement;
}

_emptyElement = false;
CharSequence chars = null;
main_loop:
while (_xmlReader.hasNext()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.XmlTestBase;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
Expand Down Expand Up @@ -105,6 +107,42 @@ public void testEmptyElementEmptyArray() throws Exception
assertEquals("", name.last);
}

public void testEmptyElementFromXmlToJsonArray() throws Exception
{
final String xml = "<name><first/><last>[]</last></name>";

XmlMapper xmlMapper = XmlMapper.builder()
.valueForEmptyElement("[]")
.build();
JsonNode jsonNode = xmlMapper.readValue(xml, JsonNode.class);

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(jsonNode);

// first is an empty tag, and is expected to be serialized
// as an empty json array, last is not empty, and is serialized as text value
String expectedJson = "{\"first\":[],\"last\":\"[]\"}";
assertEquals(expectedJson, json);
}

public void testEmptyElementFromXmlToJsonObject() throws Exception
{
final String xml = "<name><first/><last>{}</last></name>";

XmlMapper xmlMapper = XmlMapper.builder()
.valueForEmptyElement("{}")
.build();
JsonNode jsonNode = xmlMapper.readValue(xml, JsonNode.class);

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(jsonNode);

// first is an empty tag, and is expected to be serialized
// as an empty json object, last is not empty, and is serialized as text value
String expectedJson = "{\"first\":{},\"last\":\"{}\"}";
assertEquals(expectedJson, json);
}

public void testEmptyStringElement() throws Exception
{
// then with empty element
Expand Down

0 comments on commit e763443

Please sign in to comment.