{"id":15667614,"url":"https://github.com/treblereel/mapper-xml","last_synced_at":"2025-05-05T23:50:34.183Z","repository":{"id":39876106,"uuid":"248346470","full_name":"treblereel/mapper-xml","owner":"treblereel","description":"j2cl/gwt compatible XML marshallers","archived":false,"fork":false,"pushed_at":"2024-11-29T20:41:29.000Z","size":9817,"stargazers_count":4,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-19T12:14:03.206Z","etag":null,"topics":["gwt","j2cl","java","jaxb","mapper","xml"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/treblereel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-03-18T21:25:53.000Z","updated_at":"2025-04-05T09:04:23.000Z","dependencies_parsed_at":"2024-10-03T14:04:39.982Z","dependency_job_id":"56fb8883-82ba-405b-8334-382c376f8897","html_url":"https://github.com/treblereel/mapper-xml","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treblereel%2Fmapper-xml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treblereel%2Fmapper-xml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treblereel%2Fmapper-xml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treblereel%2Fmapper-xml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/treblereel","download_url":"https://codeload.github.com/treblereel/mapper-xml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252596371,"owners_count":21773843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gwt","j2cl","java","jaxb","mapper","xml"],"created_at":"2024-10-03T14:04:30.142Z","updated_at":"2025-05-05T23:50:34.155Z","avatar_url":"https://github.com/treblereel.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub license](https://img.shields.io/github/license/treblereel/mapper-xml)](https://github.com/treblereel/mapper-xml/blob/main/LICENSE)\n![Sonatype Nexus (Releases)](https://img.shields.io/nexus/r/org.treblereel.gwt.xml.mapper/processor?server=https%3A%2F%2Foss.sonatype.org\u0026style=plastic)\n![Gitter](https://img.shields.io/gitter/room/vertispan/j2cl)\n[![Java CI with Maven](https://github.com/treblereel/mapper-xml/actions/workflows/maven.yml/badge.svg)](https://github.com/treblereel/mapper-xml/actions/workflows/maven.yml)\n\n\n\n# mapper-xml\n**mapper-xml** is an annotation-processor-based XML mapper that works both on the client side - GWT and J2CL - and on the JVM side with \"Code-first\" approach.\n\nmapper-xml is a relaxed implementation of the Jakarta JAXB specification, which means that it is not 100% compatible with the JAXB specification;\n\n## Maven\n\nArtifacts are published to sonatype repo\n\n```xml\n    https://mvnrepository.com/artifact/org.treblereel.gwt.xml.mapper\n```\n\n\n## Installing xml-mapper:\n\n1. Add relevant dependencies to the `pom` file:\n\n    1.1. Add the following dependencies:\n    \n    - For the JRE environment:\n\n    ```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.fasterxml.woodstox\u003c/groupId\u003e\n      \u003cartifactId\u003ewoodstox-core\u003c/artifactId\u003e\n      \u003cscope\u003etest\u003c/scope\u003e\n      \u003cversion\u003e6.2.1\u003c/version\u003e\n    \u003c/dependency\u003e\n    ```\n\n    1.2. For both JRE and GWT2/J2CL environments, add the API and annotation processor dependencies:\n    \n    ```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003eorg.treblereel.gwt.xml.mapper\u003c/groupId\u003e\n      \u003cartifactId\u003eapi\u003c/artifactId\u003e\n      \u003cversion\u003e0.6\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n      \u003cgroupId\u003eorg.treblereel.gwt.xml.mapper\u003c/groupId\u003e\n      \u003cartifactId\u003eprocessor\u003c/artifactId\u003e\n      \u003cversion\u003e0.6\u003c/version\u003e\n      \u003cscope\u003eprovided\u003c/scope\u003e\n    \u003c/dependency\u003e\n    ```\n    \n    \u003e In case you use GWT2, add the `inherits` directive to your `gwt.xml` file:\n\n    ```xml\n      \u003cinherits name=\"org.treblereel.gwt.xml.mapper.Mapper\"/\u003e\n    ```\n\n2. Annotate POJOs with the @XMLMapper annotation:\n\n    ```xml\n    import org.treblereel.gwt.xml.mapper.api.annotation.XMLMapper;\n    \n    @XMLMapper\n    public class Person {\n    \n        private String firstName;\n        private String lastName;\n    \n        public String getFirstName() {\n            return firstName;\n        }\n    \n        public void setFirstName(String firstName) {\n            this.firstName = firstName;\n        }\n    \n        public String getLastName() {\n            return lastName;\n        }\n    \n        public void setLastName(String lastName) {\n            this.lastName = lastName;\n        }\n    }\n    ```\nSetup is complete.\n\n## Using XML mapper\n\nThe annotation processor will generate the XML mapper for the `Person` class.\n\nExample of serializing `Person` to `XML`:\n\n```xml\n  Person_XMLMapperImpl mapper = Person_XMLMapperImpl.INSTANCE;\n\n  @Test\n  public void testDeserializeValue() throws XMLStreamException {\n    Person person = new Person();\n    person.setFirstName(\"FirstName\");\n    person.setLastName(\"LastName\");\n\n    String result = mapper.write(person);\n    //\u003c?xml version='1.0' encoding='UTF-8'?\u003e\u003cPerson\u003e\u003cfirstName\u003eFirstName\u003c/firstName\u003e\u003clastName\u003eLastName\u003c/lastName\u003e\u003c/Person\u003e\n    \n  }\n```\n\nExample of deserializing to POJO:\n\n```xml\n    Person person1 = mapper.read(result);\n```\n\n## Supported annotations and data types:\n\nSupported `JAXB` annotations:\n\n* [@XmlAttribute](###xmlattribute)\n* [@XmlElement](#xmlelement)\n* [@XmlCData](#xmlcdata)\n* [@XmlTransient](#xmltransient)\n* [@XmlRootElement](#xmlrootelement)\n* [@XmlType](#xmltype)\n* [@XmlElementWrapper](#xmlelementwrapper)\n* [@XmlSchema](#xmlschema)\n* [@XmlNs](#xmlns)\n* [@XmlSeeAlso](#xmlseealso)\n* [@XmlElements](#xmlelements)\n* [@XmlElementRefs](#xmlelementrefs)\n* [@XmlElementRef](#xmlelementrefs)\n* [@XmlJavaTypeAdapter](#xmljavatypeadapter)\n* [@XmlValue](#xmlvalue)\n* [@XmlEnumValue](#xmlenumvalue)\n* XmlNsForm\n* XmlAccessorType\n* XmlAccessType\n\nSupported data types:\n\n```java\n    //primitives and boxed\n    public String stringField;\n    public byte byteField;\n    public Byte boxedByteField;\n    public short shortField;\n    public Short boxedShortField;\n    public int intField;\n    public Integer boxedIntField;\n    public long longField;\n    public Long boxedLongField;\n    public double doubleField;\n    public Double boxedDoubleField;\n    public float floatField;\n    public Float boxedFloatField;\n    public boolean booleanField;\n    public Boolean boxedBooleanField;\n    public char charField;\n    public Character boxedCharField;\n    \n    //special types\n    public BigInteger bigIntegerField;\n    public BigDecimal bigDecimalField;\n    public Date dateField;\n    public java.sql.Date sqlDateField;\n    public Time timeField;\n    public Timestamp timestampField;\n    public UUID uui;\n\n    //Enums\n    public Enum enumField;\n\n    //1 dimensional primitives arrays\n    public byte[] byteFieldArray;\n    public short[] shortFieldArray;\n    public int[] intFieldArray;\n    public long[] longFieldArray;\n    public double[] doubleFieldArray;\n    public float[] floatFieldArray;\n    public boolean[] booleanFieldArray;\n    public char[] charFieldArray;\n\n    //2 dimensional primitives arrays\n    public byte[][] byteFieldArray2d;\n    public short[][] shortFieldArray2d;\n    public int[][] intFieldArray2d;\n    public long[][] longFieldArray2d;\n    public double[][] doubleFieldArray2d;\n    public float[][] floatFieldArray2d;\n    public boolean[][] booleanFieldArray2d;\n    public char[][] charFieldArray2d;\n\n    //1 dimensional Boxed arrays\n    public String[] stringFieldArray;\n    public Byte[] boxedByteFieldArray;\n    public Short[] boxedShortFieldArray;\n    public Integer[] boxedIntFieldArray;\n    public Long[] boxedLongFieldArray;\n    public Double[] boxedDoubleFieldArray;\n    public Float[] boxedFloatFieldArray;\n    public Boolean[] boxedBooleanFieldArray;\n    public Character[] boxedCharFieldArray;\n    \n    //1 dimensional special types arrays\n    public BigInteger[] bigIntegerFieldArray;\n    public BigDecimal[] bigDecimalFieldArray;\n    public Date[] dateFieldArray;\n    public java.sql.Date[] sqlDateFieldArray;\n    public Time[] timeFieldArray;\n    public Timestamp[] timestampFieldArray;\n\n    //2 dimensional boxed arrays\n    public String[][] stringFieldArray2d;\n    public Byte[][] boxedByteFieldArray2d;\n    public Short[][] boxedShortFieldArray2d;\n    public Integer[][] boxedIntFieldArray2d;\n    public Long[][] boxedLongFieldArray2d;\n    public Double[][] boxedDoubleFieldArray2d;\n    public Float[][] boxedFloatFieldArray2d;\n    public Boolean[][] boxedBooleanFieldArray2d;\n    public Character[][] boxedCharFieldArray2d;\n    \n    //collections\n    public AbstractCollection\u003cString\u003e abstractCollection;\n    public AbstractList\u003cString\u003e abstractList;\n    public AbstractQueue\u003cString\u003e abstractQueue;\n    public AbstractSequentialList\u003cString\u003e abstractSequentialList;\n    public AbstractSet\u003cString\u003e abstractSet;\n    public ArrayList\u003cString\u003e arrayList;\n    public Collection\u003cString\u003e collection;\n    public EnumSet\u003cAnEnum\u003e enumSet;\n    public HashSet\u003cString\u003e hashSet;\n    public Iterable\u003cString\u003e iterable;\n    public LinkedHashSet\u003cString\u003e linkedHashSet;\n    public LinkedList\u003cString\u003e linkedList;\n    public List\u003cString\u003e list;\n    public PriorityQueue\u003cString\u003e priorityQueue;\n    public Queue\u003cString\u003e queue;\n    public Set\u003cString\u003e set;\n    public SortedSet\u003cString\u003e sortedSet;\n    public Stack\u003cString\u003e stack;\n    public TreeSet\u003cString\u003e treeSet;\n    public Vector\u003cString\u003e vector;\n    \n    //Maps\n    public AbstractMap\u003cString, String\u003e abstractMap;\n    public EnumMap\u003cAnEnum, Integer\u003e enumMap;\n    public HashMap\u003cInteger, Double\u003e hashMap;\n    public IdentityHashMap\u003cLong, Date\u003e identityHashMap;\n    public LinkedHashMap\u003cDouble, AnEnum\u003e linkedHashMap;\n    public Map\u003cShort, Time\u003e map;\n    public SortedMap\u003cString, Short\u003e sortedMap;\n    public TreeMap\u003cString, BigInteger\u003e treeMap;\n    \n    public AnotherBean anotherBean;\n```\n    \n## Annotations:\n    \n### @XmlAttribute\n@XmlAttribute defines the field that will be mapped as an attribute instead of an element. Name value can be used to override the attribute name.\n\nJava:\n```java\n    @XmlAttribute(name = \"_id\")\n    private int id;\n```\nXML:\n```xml\n    \u003cPerson _id=\"111\" /\u003e\n```\n    \n### @XmlElement\n@XmlElement defines the actual XML element name that will be used.\n\nJava:\n```java\n    @XmlAttribute(name = \"_id\")\n    private int id;\n```\nXML:\n```xml\n    \u003cPerson\u003e\u003c_id\u003e111\u003c/_id\u003e\u003c/Person\u003e\n```\n\n### @XmlCData\n@XmlCData defines the field that will be mapped as a CDATA section. Use it with String fields.\n\nJava:\n```java\n    @XmlCData\n    private String id;\n```  \nXML:\n```xml\n    \u003cPerson\u003e\u003cid\u003e\u003c![CDATA[111]]\u003e\u003c/id\u003e\u003cfirstName\u003eFirstName\u003c/firstName\u003e\u003clastName\u003eLastName\u003c/lastName\u003e\u003c/Person\u003e\n```\n\n### @XmlTransient\n@XmlTransient annotates fields that we don't want to include in the future XML file. It's also possible to use the transient modifier.\n\nJava:\n```java\n    @XmlTransient\n    private String id;\n``` \n```java\n    private transient String id;\n``` \n\n### @XmlRootElement\nThe name of the root XML element is derived from the class name. We can also specify the name of the root element of the XML using its name attribute.\n\nJava:\n```java\n    @XmlRootElement(name = \"person\")\n    public class Person {\n```\n    \nXML:\n```xml\n    \u003cperson\u003e\u003cid\u003e1\u003c/id\u003e\u003cfirstName\u003eFirstName\u003c/firstName\u003e\u003clastName\u003eLastName\u003c/lastName\u003e\u003c/person\u003e\n```\n    \nNamespace is used to add the `xmlns` declaration to the element.\n\nJava:\n```java\n    @XmlRootElement(name = \"person\", namespace = \"https://my.namespace\")\n    public class Person {\n```\nXML:\n```xml\n\u003cperson xmlns=\"https://my.namespace\"\u003e\u003cid\u003e1\u003c/id\u003e\u003cfirstName\u003eFirstName\u003c/firstName\u003e\u003clastName\u003eLastName\u003c/lastName\u003e\u003c/person\u003e\n```\n     \n### @XmlType\n@XmlType defines the order in which the fields are written in the XML file.\n\nJava:\n```java\n    @XMLMapper\n    @XmlType(propOrder = {\"lastName\", \"firstName\",\"id\"})\n    public class Person {\n\n    @XmlCData\n     private String id;\n     private String firstName;\n     private String lastName;\n```\nXML:\n```xml\n  \u003cPerson\u003e\u003clastName\u003eLastName\u003c/lastName\u003e\u003cfirstName\u003eFirstName\u003c/firstName\u003e\u003cid\u003e\u003c![CDATA[111]]\u003e\u003c/id\u003e\u003c/Person\u003e\n```\n\n### @XmlElementWrapper  \n@XmlElementWrapper generates a wrapper element around XML elements.\n\nJava:\n```java\n    @XmlElementWrapper(name = \"XmlElementWrapper\")\n    private String firstName;\n```\nXML:\n```xml\n  \u003cXmlElementWrapper\u003e\u003cfirstName\u003eFirstName\u003c/firstName\u003e\u003c/XmlElementWrapper\u003e\n```\n\n### @XmlSchema\n\n@XmlSchema is used on the package to set a default `namespace` attribute and specify that all elements in the package are qualified with the `namespace`. This information is specified in a special Java source file: `package-info.java`.\n \nJava:\n\n```java\n    @XmlSchema(namespace = \"http://www.omg.org/bpmn20\")\npackage org.treblereel.gwt.xml.mapper.client.tests.beans.simple;\n\nimport jakarta.xml.bind.annotation.XmlSchema;\n```\n     \nXML:\n```xml\n  \u003cPerson xmlns=\"http://www.omg.org/bpmn20\"\u003e\n```\n\nSometimes it's necessary to add `xsi:schemaLocation` to the root element. An example:\n\nJava:\n\n```java\n     @XmlSchema(namespace = \"http://www.omg.org/bpmn20\",\n        xmlns = {\n                @XmlNs(prefix = \"xsi\", namespaceURI = \"http://www.w3.org/2001/XMLSchema-instance\"),\n                @XmlNs(prefix = \"drools\", namespaceURI = \"http://www.jboss.org/drools\")\n        },\n        location =\n                \"http://www.jboss.org/drools \"\n)\npackage org.treblereel.gwt.xml.mapper.client.tests.beans.simple;\n\nimport jakarta.xml.bind.annotation.XmlNs;\nimport jakarta.xml.bind.annotation.XmlSchema;\n```\n     \nXML:\n```xml\n  \u003cPerson xmlns=\"http://www.omg.org/bpmn20\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:drools=\"http://www.jboss.org/drools\" xsi:schemaLocation=\"http://www.jboss.org/drools \"\u003e\n```\n\n@XmlType can be used to override the `namespace` declaration.\n     \n```java\n    @XmlType(namespace = \"http://www.example.org/type\")\n```\n\n### @XmlNs\n@XmlNs is used to add additional `namespace` declarations in @XmlSchema;\n\nJava:\n\n```java\n     @XmlSchema(namespace = \"http://www.omg.org/bpmn20\",\n        xmlns = {\n                @XmlNs(prefix = \"drools\", namespaceURI = \"http://www.jboss.org/drools\")\n        }\n)\npackage org.treblereel.gwt.xml.mapper.client.tests.beans.simple;\n\nimport jakarta.xml.bind.annotation.XmlNs;\nimport jakarta.xml.bind.annotation.XmlSchema;\n```\n     \nXML:\n```xml\n     \u003cPerson xmlns=\"http://www.example.org/type\" xmlns:drools=\"http://www.jboss.org/drools\"\u003e\n```\n\n### @XmlSeeAlso\n@XmlSeeAlso instructs a marshaller to also bind other classes when binding this class. Subclasses must be annotated with @XmlRootElement.\n\nJava:\n```java\n    @XmlSeeAlso({Dog.class,Cat.class})\n    class Animal {}\n    class Dog extends Animal {}\n    class Cat extends Animal {}\n    \n    public class SomeClass {\n        private Animal animal;\n    }\n```\n\nXML:\n```xml\n     \u003canimal xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"Dog\"\u003e\n```\n\n### @XmlElements\nCompared to an element property (property with XmlElement annotation), a reference property has a different substitution semantics. When a subclass is assigned to a property, an element property produces the same tag name with @xsi:type, whereas a reference property produces a different tag name (the tag name that's on the subclass.)\n\nJava: \n```java\n    @XmlElements({\n    @XmlElement(name = \"_Address1\", type = Address.class),\n    @XmlElement(name = \"_Address2\", type = Address2.class),\n    @XmlElement(name = \"_Address3\", type = Address3.class)\n    })\n    private List\u003cIAddress\u003e iAddressList;\n```\n     \nXML:\n```xml\n  \u003ciAddressList xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"_Address1\" /\u003e\n``` \n\n### @XmlElementRefs\nCompared to an element property (property with {@link XmlElement} annotation), a reference property has a different substitution semantics. When a subclass is assigned to a property, an element property produces the same tag name with @xsi:type, whereas a reference property produces a different tag name (the tag name that's on the subclass.)\n\nJava:\n```java\n    @XmlElementRefs({\n    @XmlElementRef(name = \"_Address1\", type = Address.class),\n    @XmlElementRef(name = \"_Address2\", type = Address2.class),\n    @XmlElementRef(name = \"_Address3\", type = Address3.class)\n    })\n    private List\u003cIAddress\u003e iAddressListRef;\n\n    ... iAddressListRef.add(new Address(\"AAAA\"))\n```\n    \nXML:\n```xml\n  \u003c_Address1\u003e\n    \u003caddress\u003eAAAAA\u003c/address\u003e\n  \u003c/_Address1\u003e\n```\n\n### @XmlJavaTypeAdapter\nUse an adapter that implements XmlAdapter for custom marshaling.\n* field\n* type\n* package, from within XmlJavaTypeAdapters\n\nJava:\n```java\n  @XmlJavaTypeAdapter(MyTestBeanValueAdapter.class)\n  private MyCustomBean value;\n```\n\n```java\npublic class MyTestBeanValueAdapter extends XmlAdapter\u003cMyCustomBeanType, MyCustomBean\u003e {\n\n  @Override\n  public MyCustomBean unmarshal(MyCustomBeanType v) throws Exception {\n    return new MyCustomBean(v);\n  }\n\n  @Override\n  public MyCustomBeanType marshal(MyCustomBean v) throws Exception {\n    return new MyCustomBeanType(v);\n  }\n}\n```\n\n### @XmlValue\nEnables mapping a class to a XML Schema complex type with a simpleContent or a XML Schema simple type.\n\nJava:\n```java\npublic class User {\n         @XmlValue\n         public String name;\n     }\n```\nXML:\n```xml\n\u003c?xml version='1.0' encoding='UTF-8'?\u003e\u003cUser\u003etestName\u003c/User\u003e\n```\n\n\n### @XmlEnumValue\nMaps an enum constant in Enum type to XML representation.\n\nJava:\n```java\n  public enum Enums {\n    @XmlEnumValue(\"1\")\n    ONE,\n    TWO,\n    @XmlEnumValue(\"_three\")\n    THREE,\n    FOUR\n  }\n```\nXML:\n```xml\n\u003c?xml version='1.0' encoding='UTF-8'?\u003e\u003cEnumBean\u003e\u003cval\u003e_three\u003c/val\u003e\u003c/EnumBean\u003e\n```\n    \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftreblereel%2Fmapper-xml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftreblereel%2Fmapper-xml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftreblereel%2Fmapper-xml/lists"}