- Notifications
You must be signed in to change notification settings - Fork0
perilbrain/jackson-dataformat-xml
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This projects containsJackson extension component forreading and writingXML encoded data.
Further, the goal is to emulate howJAXB data-binding workswith "Code-first" approach (that is, no support is added for "Schema-first" approach).Support for JAXB annotations is provided byJAXB annotation module;this module provides low-level abstractions (JsonParser,JsonGenerator,JsonFactory) as well as small number of higher leveloverrides needed to make data-binding work.
It is worth noting, however, that the goal is NOT to be full JAXB clone; or to be general purpose XML toolkit.
Specifically:
- While XML serialization should ideally be similar to JAXB output, deviations are not necessarily considered bugs -- we do "best-effort" matching
- What should be guaranteed is that any XML written using this module must be readable using module as well: that is, we do aim for full XML serialization.
- From above: there are XML constructs that module will not be able to handle; including some cases JAXB supports
- This module may, however, also support constructs and use cases JAXB does not handle: specifically, rich type and object id support of Jackson are supported.
master branch is for developing the next major Jackson version -- 3.0 -- but thereare active maintenance branches in which much of development happens:
2.10is for developing the next (and possibly last) minor 2.x version2.8and2.9are for backported fixes for 2.8/2.9 patch versions
Older branches are usually not changed but are available for historic reasons.All released versions have matching git tags (jackson-dataformats-text-2.9.4).
All modules are licensed underApache License 2.0.
To use Jackson 2.x compatible version of this extension on Maven-based projects, use following dependency:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.9.9</version></dependency>
(or whatever version is most up-to-date at the moment)
Also: you usually also want to make sure that XML library in use isWoodstox since it is not only faster than Stax implementation JDK provides, but also works better and avoids some known issues like adding unnecessary namespace prefixes.You can do this by adding this in yourpom.xml:
<dependency> <groupId>com.fasterxml.woodstox</groupId> <artifactId>woodstox-core</artifactId> <version>5.1.0</version></dependency>
Although module implements low-level (JsonFactory /JsonParser /JsonGenerator) abstractions,most usage is through data-binding level. This because a small number of work-arounds have been addedat data-binding level, to work around XML peculiarities: that is, stream ofJsonTokens that parserproduces has idiosyncracies that need special handling.
Usually you either createXmlMapper simply by:
XmlMappermapper =newXmlMapper();
but in case you need to configure settings, you will want to do:
JacksonXmlModulemodule =newJacksonXmlModule();// and then configure, for example:module.setDefaultUseWrapper(false);XmlMapperxmlMapper =newXmlMapper(module);// and you can also configure AnnotationIntrospectors etc here:
as many features thatXmlMapper needs are provided byJacksonXmlModule; defaultXmlMapper simply constructs module with default settings.
Alternatively, sometimes you may want/need to configure low-level XML processing detailscontrolled by underlying Stax library (Woodstox, Aalto or JDK-default Oracle implementation).If so, you will need to constructXmlMapper with properly configured underlying factories.This usually looks something like:
XMLInputFactoryifactory =newWstxInputFactory();// Woodstox XMLInputFactory implifactory.setProperty(WstxInputProperties.P_MAX_ATTRIBUTE_SIZE,32000);// configureXMLOutputFactoryofactory =newWstxOutputFactory();// Woodstox XMLOutputfactory implofactory.setProperty(WstxOutputProperties.P_OUTPUT_CDATA_AS_TEXT,true);XmlFactoryxf =newXmlFactory(ifactory,ofactory);XmlMappermapper =newXmlMapper(xf);// there are other overloads too
For configurable properties, you may want to check outConfiguring Woodstox XML parser
Usage of this library on Android is currently not supported. This is due to the fact that the Stax API is unavailable on the Android platform, and attempts to declare an explicit dependency on the Stax API library will result in errors at build time (since the inclusion of thejavax.* namespace in apps is restricted).For more on the issues, see:
- https://stackoverflow.com/questions/31360025/using-jackson-dataformat-xml-on-android
- https://www.docx4java.org/blog/2012/05/jaxb-can-be-made-to-run-on-android/
Note that as per articles linked to it MAY be possible to use the module on Android, but it unfortunately requiresvarious work-arounds and development team can not do much to alleviate these issues.Suggestions for improvements would be welcome; discussions onJackson users list encouraged.
Serialization is done very similar to JSON serialization: all that needs to change isObjectMapper instance to use:
// Important: create XmlMapper; it will use proper factories, workaroundsObjectMapperxmlMapper =newXmlMapper();Stringxml =xmlMapper.writeValueAsString(newSimple());// orxmlMapper.writeValue(newFile("/tmp/stuff.json"),newSimple());
and with POJO like:
publicclassSimple {publicintx =1;publicinty =2;}
you would get something like:
<Simple> <x>1</x> <y>2</y></Simple>
(except that by default output is not indented: you can enabled indentation using standard Jackson mechanisms)
Similar to serialization, deserialization is not very different from JSON deserialization:
ObjectMapperxmlMapper =newXmlMapper();Simplevalue =xmlMapper.readValue("<Simple><x>1</x><y>2</y></Simple>",Simple.class);
It is also possible to do incremental writes. This is done by creating StaxXMLInputFactory separately (similar to how with JSON you would createJsonGenerator), and then:
// First create Stax components we needXMLInputFactoryxmlInputFactory =XMLInputFactory.newFactory();XMLOutputFactoryxmlOutputFactory =XMLOutputFactory.newFactory();StringWriterout =newStringWriter();XMLStreamWritersw =xmlOutputFactory.createXMLStreamWriter(out);// then Jackson componentsXmlMappermapper =newXmlMapper(xmlInputFactory);sw.writeStartDocument();sw.writeStartElement("root");// Write whatever content POJOs...SomePojovalue1 = ...;OtherPojovalue2 = ...;mapper.writeValue(sw,value1);mapper.writeValue(sw,value2);// and/or regular Stax outputsw.writeComment("Some insightful commentary here");sw.writeEndElement();sw.writeEndDocument();
Similarly it is possible to read content, sub-tree by sub-tree; assuming similar XML contentwe would use
XMLInputFactoryf =XMLInputFactory.newFactory();FileinputFile = ...;XMLStreamReadersr =f.createXMLStreamReader(newFileInputStream(inputFile));XmlMappermapper =newXmlMapper();sr.next();// to point to <root>sr.next();// to point to root-element under rootSomePojovalue1 =mapper.readValue(sr,SomePojo.class);// sr now points to matching END_ELEMENT, so move forwardsr.next();// should verify it's either closing root or new start, left as exerciseOtherPojovalue =mapper.readValue(sr,OtherPojo.class);// and more, as needed, thensr.close();
In addition to standardJackson annotations and optional JAXB (javax.xml.bind.annotation), this project also adds couple of its own annotations for convenience, to support XML-specific details:
@JacksonXmlElementWrapperallows specifying XML element to use for wrappingListandMapproperties@JacksonXmlPropertyallows specifying XML namespace and local name for a property; as well as whether property is to be written as an XML element or attribute.@JacksonXmlRootElementallows specifying XML element to use for wrapping the root element (default uses 'simple name' of the value class)@JacksonXmlTextallows specifying that value of one property is to be serialized as "unwrapped" text, and not in an element.@JacksonXmlCDataallows specifying that the value of a property is to be serialized within a CData tag.
for longer description, check outXML module annotations.
Currently, following limitations exist beyond basic Jackson (JSON) limitations:
- Streaming model is only meant to be used through databinding: direct usage is possible but not supported
- Tree Model is only supported in limited fashion and its use is recommended against: since tree model is based on JSON information model, it does not match XML infoset
- Java arrays and
Collections can be written, but can not be read, since it is not possible to distinguish Arrays and Objects without additional information. - Mixed content (both textual content and elements as children of an element) not supported: text, if any, is lost
- Repeated elements with same name are handled so that only the last element is included, others are ignored
- Java arrays and
- Root value should be a POJO; and specifically following types can be serialized as properties but may not work as intended as root values
- Primitive/Wrapper values (like
java.lang.Integer) Enums- Java arrays
java.util.Collectionvalues (Lists, Sets)- Note: over time some level of support has been added, and
Collections, for example, often work.
- Primitive/Wrapper values (like
- Lists and arrays are "wrapped" by default, when using Jackson annotations, but unwrapped when using JAXB annotations (if supported, see below)
@JacksonXmlElementWrapper.useWrappingcan be set to 'false' to disable wrappingJacksonXmlModule.setDefaultUseWrapper()can be used to specify whether "wrapped" or "unwrapped" setting is the default
- XML modulewiki page for more information
- Using XML withDropWizard? Check outthis extension!
About
Extension for Jackson JSON processor that adds support for serializing POJOs as XML (and deserializing from XML) as an alternative to JSON
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Languages
- Java98.3%
- Logos1.7%