JAXB: Remove parent node keeping it's children - java

I know it doesn't make much sense, but I have to generate an XML from a Java object without the parent node of some elements, like explained below.
This is the example Java class model for the XML:
#XmlRootElement(name = "person")
public class PersonXml {
#XmlElement(name = "name")
private String name;
#XmlElement(name = "car")
private List<CarXml> cars;
.
#XmlRootElement(name = "car")
public class CarXml {
#XmlElement(name = "model")
private String model;
#XmlElement(name = "brand")
private String brand;
By default, if I generate the XML from an object of PersonXml like this:
StringWriter writer = new StringWriter();
JAXBContext ctx = JAXBContext.newInstance(PersonXml.class);
Marshaller marshaller = ctx.createMarshaller();
marshaller.marshal(xml, writer);
I would get:
<person>
<name>Pedro</name>
<car>
<model>Logan</model>
<brand>Renault</brand>
</car>
<car>
<model>Duster</model>
<brand>Renault</brand>
</car>
</person>
What I need is to remove the <car> tag, or even to prevent it to be generated at all.
I need the XML to be like this:
<person>
<name>Pedro</name>
<model>Logan</model>
<brand>Renault</brand>
<model>Duster</model>
<brand>Renault</brand>
</person>
Of course I could convert the XML to a String and remove the tags with replaceAll or something like this, but I was wondering if there is a nicer way to achieve this.

If you need to generate this output, you can use JAXB as follows:
1) Create a new Person class:
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"field"
})
#XmlRootElement(name = "person")
public class Person {
#XmlElementRefs({
#XmlElementRef(name = "name", type = JAXBElement.class, required = false),
#XmlElementRef(name = "model", type = JAXBElement.class, required = false),
#XmlElementRef(name = "brand", type = JAXBElement.class, required = false)
})
protected List<JAXBElement<String>> field;
public List<JAXBElement<String>> getNameOrModelOrBrand() {
if (field == null) {
field = new ArrayList<>();
}
return this.field;
}
}
2) Create an ObjectFactory to make it easier to use the person class:
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
#XmlRegistry
public class ObjectFactory {
private final static QName _PersonName_QNAME = new QName("", "name");
private final static QName _PersonModel_QNAME = new QName("", "model");
private final static QName _PersonBrand_QNAME = new QName("", "brand");
public ObjectFactory() {
}
public Person createPerson() {
return new Person();
}
#XmlElementDecl(namespace = "", name = "name", scope = Person.class)
public JAXBElement<String> createPersonName(String value) {
return new JAXBElement<>(_PersonName_QNAME, String.class, Person.class, value);
}
#XmlElementDecl(namespace = "", name = "model", scope = Person.class)
public JAXBElement<String> createPersonModel(String value) {
return new JAXBElement<>(_PersonModel_QNAME, String.class, Person.class, value);
}
#XmlElementDecl(namespace = "", name = "brand", scope = Person.class)
public JAXBElement<String> createPersonBrand(String value) {
return new JAXBElement<>(_PersonBrand_QNAME, String.class, Person.class, value);
}
}
Use the factory as follows:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.util.List;
...
ObjectFactory factory = new ObjectFactory();
Person person = factory.createPerson();
List<JAXBElement<String>> list = person.getNameOrModelOrBrand();
list.add(factory.createPersonName("Pedro"));
list.add(factory.createPersonModel("Logan"));
list.add(factory.createPersonBrand("Renault"));
list.add(factory.createPersonModel("Duster"));
list.add(factory.createPersonBrand("Renault"));
JAXBContext ctx = JAXBContext.newInstance(Person.class);
Marshaller marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter writer = new StringWriter();
marshaller.marshal(person, writer);
System.out.println(writer.toString());
The end result is XML as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<name>Pedro</name>
<model>Logan</model>
<brand>Renault</brand>
<model>Duster</model>
<brand>Renault</brand>
</person>
Creating elements in this way is the only way I know to get the end result you need.
There are probably various things you could do to refactor the above code, to streamline the creation of the list of elements - but this shows you the basic approach.
As you already know - this is far from ideal. The end result is not any type of XML that I would want to receive.

Related

Create XML string in java with custom namespace

I want to generate xml string in java programmatically whose name space is custom as shown below
and all data must come dynamically in xml.How can I achieve something like this?
<faxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="test.xsd">
<person>
<name>ABC</name>
</person>
</faxml>
I have gone through examples like this https://howtodoinjava.com/jaxb/write-object-to-xml/ but here when xml generated its starting line is
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
but I want start and end tag <faxml> and namespaces as I mentioned in my sample code as output
Here is one approach:
First, here is my class representing the required XML data:
package org.ajames.jaxb.persons;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "")
#XmlRootElement(name = "faxml")
public class Faxml {
private Person person;
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
I chose to nest the Person class inside the root class - just for this test. There are other ways to arrange these classes, of course, so they are not nested.
Then I define the package-info for org.ajames.jaxb.persons as follows:
#XmlSchema(
namespace = "",
elementFormDefault = XmlNsForm.UNSET,
xmlns = {
#XmlNs(prefix = "", namespaceURI = "http://www.w3.org/2001/XMLSchema-instance")
})
package org.ajames.jaxb.persons;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
To process the data from a Java object to XML, I use the following test data:
Faxml.Person person = new Faxml.Person();
person.setName("ABC");
Faxml faxml = new Faxml();
faxml.setPerson(person);
The JAXB context and marshaller are as follows, assuming we are writing the XML to a Java String, for this test:
JAXBContext jaxbContext = JAXBContext.newInstance(Faxml.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "test.xsd");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter stringWriter = new StringWriter();
marshaller.marshal(faxml, stringWriter);
String xml = stringWriter.toString();
System.out.println(xml);
The resulting XML is:
<faxml xsi:noNamespaceSchemaLocation="test.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<person>
<name>ABC</name>
</person>
</faxml>
String name= "name"
String createXml="<faxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"//
xsi:noNamespaceSchemaLocation="test.xsd">"//
+"<person>"//
+"<name>"+name+"</name>"//
+"</>person">"//
+"</faxml>";
Sysout(createXml);
get the name in a variable. Hard code these lines and insert it like this..

Binding a child object of an XmlElement list to a Java object using Jackson XmlMapper

Given the following xml:
<?xml version="1.0" encoding="utf-8"?>
<live_schedules>
<title>This Schedule</title>
<date>20190328</date>
<link>/v2/schedule</link>
<id>schedule</id>
<updated>2019-03-28T21:51:41+0</updated>
<schedule>
<sport id="1" name="Football" link="/v2/sport/1">
<league id="100" name="Alliance of American Football" link="/v2/league/100" />
<league id="101" name="Alliance of American Football" link="/v2/league/101" />
</sport>
</schedule>
</live_schedules>
And also given the following classes:
LiveScheduleDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#Data
#AllArgsConstructor
#XmlRootElement(name = "live_schedule")
#XmlAccessorType(XmlAccessType.FIELD)
public class LiveScheduleWrapper {
#XmlElement(name = "title")
private String title;
#XmlElement(name = "date")
private String date;
#XmlElement(name = "link")
private String link;
#XmlElement(name = "id")
private String id;
#XmlElement(name = "updated")
private String updatedDate;
#XmlElement(name = "schedule")
private ScheduleDto schedule;
}
ScheduleDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
#AllArgsConstructor
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "schedule")
class ScheduleDto {
#XmlElement(name = "sport")
List<SportDto> sports;
}
SportDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.xml.bind.annotation.*;
import java.util.List;
#Data
#AllArgsConstructor
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "sport")
public class SportDto {
#XmlAttribute(name = "id")
Integer id;
#XmlAttribute(name = "name")
String name;
#XmlAttribute(name = "link")
String link;
#XmlElementWrapper(name = "league")
List<LeagueDto> league;
}
LeagueDto.java
package com.stackoverflow.dto;
import lombok.AllArgsConstructor;
import javax.xml.bind.annotation.*;
#AllArgsConstructor
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "league")
public class LeagueDto {
#XmlAttribute(name = "id")
String id;
#XmlAttribute(name = "name")
String name;
#XmlAttribute(name = "link")
String link;
}
The adaptor that performs the mapping:
package com.stackoverflow.adaptors;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import com.stackoverflow.dto.LiveScheduleWrapper;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import java.io.IOException;
public class ScheduleAdaptor {
private final HttpClient httpClient;
private final HttpGet httpGet;
public ScheduleAdaptor(HttpClient httpClient, HttpGet httpGet) {
this.httpClient = httpClient;
this.httpGet = httpGet;
}
public HttpApiResponse<LiveScheduleWrapper> retrieveSchedule() {
try {
HttpResponse response = httpClient.execute(httpGet);
XmlMapper mapper = new XmlMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);
LiveScheduleWrapper schedule =
mapper.readValue(response.getEntity().getContent(), LiveScheduleWrapper.class);
return new HttpApiResponse(response.getStatusLine().getStatusCode(), schedule);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
I am seeing when I run this through a parser that it is binding the SportDto to the LeagueDto because I've defined the <sport> element as a List. This isn't what I expected. Instead I expected that it would bind the Sport XmlElement to the SportDto object then the League to the nested League object as I've defined in my example.
What's the easiest way to correctly bind the <sport> xml element list to SportDto and the <league> xml element list to the LeagueDto?
I should make it clear I'm using Jacksons XmlMapper not JAXBContext
I managed to fix it. My issue was because I used the Jackson XmlMapper which isn't as full featured as the JAXBContext library...
I replaced my retrieveSchedule function with the following:
public HttpApiResponse<LiveScheduleWrapper> retrieveSchedule() {
try {
HttpResponse response = httpClient.execute(httpGet);
JAXBContext jc = JAXBContext.newInstance(LiveScheduleWrapper.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
LiveScheduleWrapper schedule = (LiveScheduleWrapper) unmarshaller.unmarshal(response.getEntity().getContent());
return new HttpApiResponse(response.getStatusLine().getStatusCode(), schedule);
} catch (JAXBException | IOException e) {
e.printStackTrace();
}
return null;
}
This solved my issue because JAXBContext correctly recognises JAXB annotations over XmlMapper.

Marshalling with XSD choice field in class

I use a Java class to generate the WSDL schema dynamically. I have this as one of my fields:
#XmlElements({
#XmlElement(name = "A", type = String.class),
#XmlElement(name = "B", type = Integer.class),
#XmlElement(name = "C", type = String.class),
#XmlElement(name = "D", type = String.class)
})
protected Object aOrBOrCOrD;
During marshalling, when the single choice property aOrBOrCOrD is set, which tag name(A, B, C or D) would be set in the XML?
Since there's only one field which would contain the data. And String could also mean any 1 of the 3 choice elements. How to get around this?
Can I split the single field in 4 and still maintain the choice property when the WSDL is generated somehow?
You could do the following:
Java Model
Foo
Instead of #XmlElements and a property of type Object, you can use #XmlElementRefs and a property of type JAXBElement. A JAXBElement allows you to preserve the element name.
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
#XmlElementRefs({
#XmlElementRef(name = "A", type = JAXBElement.class),
#XmlElementRef(name = "B", type = JAXBElement.class),
#XmlElementRef(name = "C", type = JAXBElement.class),
#XmlElementRef(name = "D", type = JAXBElement.class)
})
protected JAXBElement<?> aOrBOrCOrD;
}
ObjectFactory
Along with #XmlElementRef you need to have a corresponding #XmlElementDec annotations on a class annotated with #XmlRegistry.
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
#XmlRegistry
public class ObjectFactory {
#XmlElementDecl(name="A")
public JAXBElement<String> createA(String value) {
return new JAXBElement<String>(new QName("A"), String.class, value);
}
#XmlElementDecl(name="B")
public JAXBElement<Integer> createB(Integer value) {
return new JAXBElement<Integer>(new QName("B"), Integer.class, value);
}
#XmlElementDecl(name="C")
public JAXBElement<String> createC(String value) {
return new JAXBElement<String>(new QName("C"), String.class, value);
}
#XmlElementDecl(name="D")
public JAXBElement<String> createD(String value) {
return new JAXBElement<String>(new QName("D"), String.class, value);
}
}
Demo Code
Demo
import java.io.StringReader;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class, ObjectFactory.class);
StringReader xml = new StringReader("<foo><C>Hello World</C></foo>");
Unmarshaller unmarshaller = jc.createUnmarshaller();
Foo foo = (Foo) unmarshaller.unmarshal(xml);
JAXBElement<?> aOrBOrCOrD = foo.aOrBOrCOrD;
System.out.println(aOrBOrCOrD.getName().getLocalPart());
System.out.println(aOrBOrCOrD.getDeclaredType());
System.out.println(aOrBOrCOrD.getValue());
}
}
Output
C
class java.lang.String
Hello World

require either one element or the other in JAXB

I have a JAXB-annotated POJO like this:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Clazz implements Serializable {
#XmlElement(required = false)
private int a;
#XmlElement(required = false)
private int b;
}
I want to mark that either field a or field b is required. With my current set-up, none of them are required, but I want one of them to be present and not the other. How could I achieve it?
You can do the following with #XmlElementRefs
Domain Model
Clazz
import java.io.Serializable;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Clazz implements Serializable {
#XmlElementRefs({
#XmlElementRef(name="a", type=JAXBElement.class),
#XmlElementRef(name="b", type=JAXBElement.class)
})
private JAXBElement<Integer> aOrB;
}
ObjectFactory
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
#XmlRegistry
public class ObjectFactory {
#XmlElementDecl(name = "a")
public JAXBElement<Integer> createA(Integer integer) {
return new JAXBElement<Integer>(new QName("a"), Integer.class, integer);
}
#XmlElementDecl(name = "b")
public JAXBElement<Integer> createB(Integer integer) {
return new JAXBElement<Integer>(new QName("b"), Integer.class, integer);
}
}
Demo Code
Demo
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Clazz.class, ObjectFactory.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum22502171/input.xml");
Clazz clazz = (Clazz) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(clazz, System.out);
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8"?>
<clazz>
<b>123</b>
</clazz>

JAXB mappable XML elements

In the root.class from my xi-schema, the element item and ohter objects are part of an itemList:
#XmlElementRef(name = "item", namespace = "xi", type = JAXBElement.class, required = false)
//...
protected List<Object> itemList;
I've in the ObjectFactory.class from the main-schema some items as JAXBElements like this:
#XmlElementDecl(namespace = "de-schema", name = "detailedInformation", substitutionHeadNamespace = "xi", substitutionHeadName = "item")
public JAXBElement<numItemType> createDetailedInformation(numItemType num) {
return new JAXBElement<numItemType>(_detailedInformation_QNAME, numItemType.class, null, num);
}
So the numItemType has some attributes and value(num) for the JAXBElement.
NumItemType.class:
#XmlJavaTypeAdapter(numItemTypeAdapter.class)
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "numItemType", namespace = "xi", propOrder = {
"num"
})
public class NumItemType {
#XmlValue
protected BigDecimal num;
#XmlAttribute(name = "precision")
protected String precision;
#XmlAttribute(name = "decimals")
protected String decimals;
//... more Attributes
}
But when JAXB unmarshal the XML document, it will has only elements, for example:
<detailedInformation>
<element1>1234</element1>
<element2>5678</element2>
<element3>bla</element3>
</detailedInformation>
When I marshal it, it should become (like the JAXB java code):
<detailedInformation element2="5678" element3="bla">1234</detailedInformation>
Therefore, I have written an numItemTypeAdapter.class with
NumItemTypeAdapter extends XmlAdapter
AdaptedNum.class:
public class AdaptedNum {
#XmlElement
private double element1;
#XmlElement
private String element2;
#XmlElement
private String element3;
/** Some getter/setter methods */
}
I thought, that would be help me http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html, but it is all a bit tricky :-/
It's a bit tricky to sort out exactly where your problem may be occurring. I'm assuming your original model was generated from an XML Schema, this should work as is without any modifications. I've attempted below to provide a scaled down version of your example which may help.
Root
package forum11343610;
import java.util.*;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Root {
#XmlElementRef(name = "item", namespace = "xi", type = JAXBElement.class, required = false)
protected List<Object> itemList = new ArrayList<Object>();
public List<Object> getItemList() {
return itemList;
}
public void setItemList(List<Object> itemList) {
this.itemList = itemList;
}
}
NumItemType
package forum11343610;
import java.math.BigDecimal;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "numItemType", namespace = "xi", propOrder = {
"num"
})
public class NumItemType {
#XmlValue
protected BigDecimal num;
#XmlAttribute(name = "precision")
protected String precision;
#XmlAttribute(name = "decimals")
protected String decimals;
//... more Attributes
}
ObjectFactory
package forum11343610;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
#XmlRegistry
public class ObjectFactory {
private static final QName _detailedInformation_QNAME = new QName("de-schema", "detailedInformation");
#XmlElementDecl(namespace = "xi", name = "item")
public JAXBElement<NumItemType> createItem(NumItemType num) {
return new JAXBElement<NumItemType>(_detailedInformation_QNAME, NumItemType.class, null, num);
}
#XmlElementDecl(namespace = "de-schema", name = "detailedInformation", substitutionHeadNamespace = "xi", substitutionHeadName = "item")
public JAXBElement<NumItemType> createDetailedInformation(NumItemType num) {
return new JAXBElement<NumItemType>(_detailedInformation_QNAME, NumItemType.class, null, num);
}
}
Demo
package forum11343610;
import java.math.BigDecimal;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class, ObjectFactory.class);
ObjectFactory objectFactory = new ObjectFactory();
Root root = new Root();
NumItemType numItemType = new NumItemType();
numItemType.num = BigDecimal.TEN;
numItemType.decimals = "1";
numItemType.precision = "2";
root.getItemList().add(objectFactory.createDetailedInformation(numItemType));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns:ns2="de-schema" xmlns:ns3="xi">
<ns2:detailedInformation precision="2" decimals="1">10</ns2:detailedInformation>
</root>
Thank your for your comment.
That's the point:
Demo
NumItemType numItemType = new NumItemType();
numItemType.num = BigDecimal.TEN;
numItemType.decimals = "1";
numItemType.precision = "2";
root.getItemList().add(objectFactory.createDetailedInformation(numItemType));
It should unmarshal and map the XML automatically.
XML Input
<detailedInformation>
<element1>1234</element1>
<element2>5678</element2>
<element3>bla</element3>
</detailedInformation>
With the Code:
Demo
JAXBContext jc = JAXBContext.newInstance(Root.class, ObjectFactory.class);
Unmarshaller u = jc.createUnmarshaller();
File xml = new File("D:/", "test.xml");
Root root = (Root) u.unmarshal(xml);
Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns:ns2="de-schema" xmlns:ns3="xi">
<ns2:detailedInformation precision="2" decimals="1">10</ns2:detailedInformation>
</root>
I could parse the XML Document with DOM to a tree and marhalling with JAXB...
Thank you!
In other words:
I want to set new elements to the NumItemType.class for the unmarshalling without change the schema java code.
NumItemType.class
package forum11343610;
import java.math.BigDecimal;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "numItemType", namespace = "xi", propOrder = {
"num"
})
#XmlJavaTypeAdapter(NumItemTypeAdapter.class)
public class NumItemType {
#XmlValue
protected BigDecimal num;
#XmlAttribute(name = "precision")
protected String precision;
#XmlAttribute(name = "decimals")
protected String decimals;
//... more Attributes
}
NumItemTypeAdapter.class
public class NumItemTypeAdapter extends XmlAdapter<AdaptedNum, NumItemType> {
#Override
public NumItemType unmarshal(AdaptedNum an) throws Exception {
NumItemType nit = new NumItemType();
nit.setNum(an.getNum);
nit.setPrecision(an.getPrecision);
nit.setDecimals(an.getDecimals)
return nit;
}
}
AdaptedNum.class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "adaptedNum", namespace = "", propOrder = {
"element1",
"element2",
"element3"
})
public class AdaptedNum {
#XmlElement(name ="element1")
protected BigDecimal num;
#XmlElement(name ="element2")
private String decimals;
#XmlElement(name ="element3")
private String precison;
// set/get method
}

Categories

Resources