#XmlSeeAlso doesn't work for the same root node - java

I'm trying to implement inheritance with #XmlSeeAlso annotation. Everything works as expected when using different root node names for subclasses. But with the same root names Unmarshaller always choses the last class from the XmlSeeAlso list despite of the content. It's impossible to change root names. Is where any way to make Unmarshaller to chose class correctly by content?
import java.io.ByteArrayInputStream;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.transform.stream.StreamSource;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
public class Test {
public static void main(String[] args) {
Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
unmarshaller.setClassesToBeBound(Parent.class);
System.out.println(unmarshaller.unmarshal(new StreamSource(
new ByteArrayInputStream("<value><a>AAA</a><b>BBB</b></value>"
.getBytes()))));
System.out.println(unmarshaller.unmarshal(new StreamSource(
new ByteArrayInputStream("<value><c>CCC</c><d>DDD</d></value>"
.getBytes()))));
}
#XmlSeeAlso({ ChildAB.class, ChildCD.class })
public static abstract class Parent {
}
#XmlRootElement(name = "value")
public static class ChildAB {
#XmlElement(name = "a")
private String a;
#XmlElement(name = "b")
private String b;
#Override
public String toString() {
return "ChildAB[" + a + "; " + b + "]";
}
}
#XmlRootElement(name = "value")
public static class ChildCD {
#XmlElement(name = "c")
private String c;
#XmlElement(name = "d")
private String d;
#Override
public String toString() {
return "ChildCD[" + c + "; " + d + "]";
}
}
}
Output:
ChildCD[null; null]
ChildCD[CCC; DDD]

Why your class ChildAB and ChildCD are static? Also ChildAB and ChildCD should implement/extend your Parent class.

Related

Jaxb unmarshalls empty list with namespace [duplicate]

This question already has an answer here:
Issue with namespaces in XMLs in JAXB unmarshalling
(1 answer)
Closed 8 years ago.
I have a simple xml to unmarshall. But I get only an empty list in the output. No exceptions are thrown.
This is a third party generated xml and I need to make this work without any changes in the xml.
The XML:
<Animal xmlns="http://allmycats.com/serviceplatform/1.0/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Cat z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<name>kitty</name>
</Cat>
<Cat z:Id="i2" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<name>kitty2</name>
</Cat>
</Animal>
The POJO bean for Animal:
#XmlRootElement(name = "Animal",namespace = "http://allmycats.com/serviceplatform/1.0/")
public class Animal{
List<Cat> cats;
#XmlElement(name = "Cat")
public List<Cat> getCats() {
return cats;
}
public void setCats(List<Cat>cats) {
this.cats= cats;
}
}
The POJO bean for Cat
#XmlRootElement(name = "Cat")
public class Cat {
private String zId;
private String name;
#XmlAttribute(name = "Id", namespace="http://schemas.microsoft.com/2003/10/Serialization/")
public String getzId() {
return zId;
}
public void setzId(String zId) {
this.zId = zId;
}
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The unmarshall code is:
File file = new File(filepath);
System.out.println("file exists? : "+ file.exists()); // prints true
JAXBContext jaxbContext = JAXBContext.newInstance(Animal2.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Animal2 animals = (Animal2)jaxbUnmarshaller.unmarshal( file );
System.out.println("--file size: "+animals.getCats().size());
The last line gives a null pointer exception.
Am I doing something wrong with the namespaces in the BEAN classes? I am new to Jaxb and this issue is bugging me for 3 days now !
I asked this question earlier but couldn't get proper answer and this is a more precise question.
Animal.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
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 javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "Animal",namespace = "http://allmycats.com/serviceplatform/1.0/")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Animal", propOrder = {
"cats"
})
public class Animal implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#XmlElement(name = "Cat")
protected List<Cat> cats;
public List<Cat> getCats() {
if (cats == null) { // This solve the nullpointer
cats = new ArrayList<Cat>();
}
return this.cats;
}
}
Cat.java
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "Cat")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Cat", propOrder = {
"name"
})
public class Cat implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#XmlAttribute(name = "Id", namespace="http://schemas.microsoft.com/2003/10/Serialization/")
private String zId;
#XmlElement(name = "name")
private String name;
public String getzId() {
return zId;
}
public void setzId(String zId) {
this.zId = zId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

Can't unmarchall elements from XML file with JAXB

I want to convert context of xml file to java object.
But some part is extracted ok, and some has null values.
Here is xml file:
<OTA_AirLowFareSearchRQ EchoToken="50987" SequenceNmbr="1" Target="Production" TimeStamp="2003-11-19T19:44:10-05:00"
Version="2.001"
xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_AirLowFareSearchRQ.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.opentravel.org/OTA/2003/05">
<POS>
<TPA_Extensions>
<TPA_Extension>
<PromoRatesRequired Value="false"/>
<UserName Value="342561"/>
<UserPassword Value="1234"/>
<ClearCache Value="true"/>
</TPA_Extension>
</TPA_Extensions>
</POS>
<OriginDestinationInformation>
<DepartureDateTime>2015-04-13T00:00:00</DepartureDateTime>
<OriginLocation LocationCode="DUB"/>
<DestinationLocation LocationCode="CDG"/>
</OriginDestinationInformation>
<TravelPreferences>
<CabinPref PreferLevel="Preferred" Cabin="Economy"/>
</TravelPreferences>
<TravelerInfoSummary>
<AirTravelerAvail>
<PassengerTypeQuantity Code="ADT" Quantity="1"/>
<PassengerTypeQuantity Code="CHD" Quantity="0"/>
<PassengerTypeQuantity Code="INF" Quantity="1"/>
</AirTravelerAvail>
</TravelerInfoSummary>
</OTA_AirLowFareSearchRQ>
I have trouble with extracting 'OriginDestinationInformation' and 'AirTravelerAvail'.
Here is main():
public static void main(String[] args) {
try {
JAXBContext context = JAXBContext.newInstance(OTAAirLowFareSearchRQ.class);
Unmarshaller um = context.createUnmarshaller();
OTAAirLowFareSearchRQ rq = (OTAAirLowFareSearchRQ) um.unmarshal(new FileReader(FILE_NAME));
System.out.println(rq);
} catch (FileNotFoundException | JAXBException e) {
LOGGER.error(e);
}
}
Here is output snippet:
originDestinationInformation=[OriginDestinationInformation{
departureDateTime=null,
originLocation=null,
destinationLocation=null,
alternateLocationInfo=null,
rph='null',
refNumber=null}],
travelerInfoSummary=TravelerInfoSummary{
ticketingCountryCode='null',
specificPTCIndicator=null,
airTravelerAvails=null},
echoToken='50987',
timeStamp=2003-11-19T19:44:10-05:00,
target='Production',
version=2.001,
transactionIdentifier='null',
sequenceNmbr=1,
And much more interesting part OriginDestinationInformation:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "OriginDestinationInformation", propOrder = {
"departureDateTime",
"originLocation",
"destinationLocation",
"tpaExtensions",
"alternateLocationInfo",
"rph",
"refNumber"
})
public static class OriginDestinationInformation extends OriginDestinationInformationType {
#XmlElement(name = "DepartureDateTime", required = true)
protected TimeInstantType departureDateTime;
#XmlElement(name = "OriginLocation", required = true)
protected OriginLocation originLocation;
#XmlElement(name = "DestinationLocation", required = true)
protected DestinationLocation destinationLocation;
#Transient
#XmlElement(name = "AlternateLocationInfo")
protected AlternateLocationInfo alternateLocationInfo;
#XmlElement(name = "TPA_Extensions")
protected TPAExtensionsType tpaExtensions;
#XmlAttribute(name = "RPH")
protected String rph;
#XmlAttribute(name = "RefNumber")
protected Integer refNumber;
// getters and setters
TimeInstantType:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "TimeInstantType", propOrder = {
"value"
})
public class TimeInstantType {
#Property("dateTime")
#XmlValue
protected String value;
// rest of class
OriginLocation:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "OriginLocation")
public static class OriginLocation extends LocationType {
#XmlAttribute(name = "MultiAirportCityInd")
protected Boolean multiAirportCityInd;
#XmlAttribute(name = "AlternateLocationInd")
protected Boolean alternateLocationInd;
#XmlAttribute(name = "LocationCode")
protected String locationCode;
DestinationLocation:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "DestinationLocation")
public static class DestinationLocation extends LocationType {
#XmlAttribute(name = "MultiAirportCityInd")
protected Boolean multiAirportCityInd;
#XmlAttribute(name = "AlternateLocationInd")
protected Boolean alternateLocationInd;
#XmlAttribute(name = "LocationCode")
protected String locationCode;
and for list of objects TravelerInfoSummary
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "TravelerInfoSummary", propOrder = {
"airTravelerAvails",
"ticketingCountryCode",
"specificPTCIndicator"
})
public static class TravelerInfoSummary extends TravelerInfoSummaryType {
#Embedded
#XmlElement(name = "AirTravelerAvail")
protected List<AirTravelerAvail> airTravelerAvails;
AirTravelerAvail:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "AirTravelerAvail")
public class AirTravelerAvail {
#Embedded
#XmlElement(name = "PassengerTypeQuantity")
#XmlElementWrapper(name = "AirTravelerAvail")
protected List<PassengerTypeQuantity> passengerTypeQuantities;
I couldn't figure out what is wrong here. I tried
#XmlElementWrapper(name = "AirTravelerAvail")
for list of objects but it keep getting null.
How to solve this trouble?
To start off, I hate JAXB!
That said, i literally have to specify
#XmlElemnt(namespace = "namespace")
on every element of a class. JAXB simply does not assign the default namespace to the current xml dom.
By default, JAXB seems to work with ElementFormDefault="unqualified" and AttributeFormDefault="qualified" (I may have confused this), but this makes it unmarshall the root element, considering only attributes as belonging to the default-namespace.
If the namespace has a prefix e.g. xmlns:ns="namespace", then JAXB will correctly marshall elements as to belonging to this namespace.
If you have control over xml, simply have a prefix to the default namespace, like
xmlns:ns="http://www.opentravel.org/OTA/2003/05"
If you dont, make sure to have
#XmlElement(namespace = "http://www.opentravel.org/OTA/2003/05")
on every element that is not an attribute.
package com.anosym.stackoverflow.stackoverflow;
import java.util.Calendar;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import static com.anosym.stackoverflow.stackoverflow.Main.calendarString;
import static javax.xml.bind.annotation.XmlAccessType.FIELD;
#XmlRootElement(name = "OTA_AirLowFareSearchRQ", namespace = "http://www.opentravel.org/OTA/2003/05")
#XmlAccessorType(FIELD)
public class OTAAirLowFareSearchRQ {
#XmlAttribute(name = "EchoToken")
private String echoToken;
#XmlAttribute(name = "SequenceNmbr ")
private int sequenceNmbr;
#XmlAttribute(name = "Target")
private String target;
#XmlAttribute(name = "TimeStamp")
private Calendar timeStamp;
#XmlAttribute(name = "Version")
private String version;
#XmlElement(name = "POS", namespace = "http://www.opentravel.org/OTA/2003/05")
private POS pos;
#XmlElement(name = "OriginDestinationInformation", namespace = "http://www.opentravel.org/OTA/2003/05")
private OriginDestinationInformation destinationInformation;
public OTAAirLowFareSearchRQ(String echoToken, int sequenceNmbr, String target, Calendar timeStamp, String version,
POS pos, OriginDestinationInformation destinationInformation) {
this.echoToken = echoToken;
this.sequenceNmbr = sequenceNmbr;
this.target = target;
this.timeStamp = timeStamp;
this.version = version;
this.pos = pos;
this.destinationInformation = destinationInformation;
}
public OTAAirLowFareSearchRQ() {
}
#Override
public String toString() {
return "OTAAirLowFareSearchRQ{"
+ "echoToken=" + echoToken + ", "
+ "sequenceNmbr=" + sequenceNmbr + ", "
+ "target=" + target + ", "
+ "timeStamp=" + calendarString(timeStamp) + ", "
+ "version=" + version + ", "
+ "pos=" + pos + ", "
+ "destinationInformation=" + destinationInformation + '}';
}
}
package com.anosym.stackoverflow.stackoverflow;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import static javax.xml.bind.annotation.XmlAccessType.FIELD;
#XmlAccessorType(FIELD)
public class POS {
#XmlElement(name = "TPA_Extension", namespace = "http://www.opentravel.org/OTA/2003/05")
#XmlElementWrapper(name = "TPA_Extensions", namespace = "http://www.opentravel.org/OTA/2003/05")
private List<TPAExtension> tpaExtensions;
public POS(List<TPAExtension> tpaExtensions) {
this.tpaExtensions = tpaExtensions;
}
public POS() {
}
#Override
public String toString() {
return "POS{" + "tpaExtensions=" + tpaExtensions + '}';
}
}

There's no ObjectFactory with an #XmlElementDecl when there is static class

I am getting below exception, i need some help to resolve the issue.
If remove the namespace in the object factory and with out package-info.java class it is working fine.
Exception that is throwing now
Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
There's no ObjectFactory with an #XmlElementDecl for the element {}shipping.
this problem is related to the following location:
at protected javax.xml.bind.JAXBElement com.jverstry.annotations.generics.Market$Detail.shipping
at com.jverstry.annotations.generics.Market$Detail
at protected com.jverstry.annotations.generics.Market$Detail com.jverstry.annotations.generics.Market.detail
at com.jverstry.annotations.generics.Market
ObjectFactory class which is creating the jaxbelement
package com.jverstry.annotations.generics;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
import org.example.customer.Customer;
#XmlRegistry
public class ObjectFactory {
public ObjectFactory() {
}
public Market.Detail.Shipping createShipping() {
return new Market.Detail.Shipping();
}
private final static QName _Shipping_QNAME = new QName("http://www.example.org/customer", "shipping");
#XmlElementDecl(namespace = "http://www.example.org/customer", name = "shipping")
public JAXBElement<Market.Detail.Shipping> createShipping(Market.Detail.Shipping value) {
return new JAXBElement<Market.Detail.Shipping>(_Shipping_QNAME, Market.Detail.Shipping.class, value);
}
}
Class package-info.java, where the name spaces are mentioned for the response xml
#XmlSchema(namespace = "http://www.example.org/customer", elementFormDefault = XmlNsForm.QUALIFIED)
package com.jverstry.annotations.generics;
import javax.xml.bind.annotation.*;
Demo class where marshalling object
package com.jverstry.annotations.generics;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Market.class);
Market market = new Market();
Market.Detail md = new Market.Detail();
Market.Detail.Shipping mds = new Market.Detail.Shipping();
mds.setAvailable(false);
JAXBElement<Market.Detail.Shipping> shipping = new ObjectFactory().createShipping(mds);
shipping.setNil(true);
md.setShipping(shipping);
market.setDetail(md);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(market, System.out);
}
}
Market class, this is the main root class where jaxbcontext is created
package com.jverstry.annotations.generics;
import java.math.BigDecimal;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = { "detail" })
#XmlRootElement(name = "Market")
public class Market
{
#XmlElement(required = false)
protected Market.Detail detail;
public Market.Detail getDetail() {
return detail;
}
public void setDetail(Market.Detail detail) {
this.detail = detail;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = { "shipping" })
public static class Detail
{
#XmlElementRef(name = "shipping")
protected JAXBElement<Market.Detail.Shipping> shipping;
public JAXBElement<Market.Detail.Shipping> getShipping() {
return shipping;
}
public void setShipping(JAXBElement<Market.Detail.Shipping> value) {
this.shipping = value;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = { "value" })
public static class Shipping
{
#XmlValue
protected BigDecimal value;
#XmlAttribute(name = "available")
protected Boolean available;
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public Boolean getAvailable() {
return available;
}
public void setAvailable(Boolean value) {
this.available = value;
}
}
}
}
You need to create the JAXBContext by passing in the ObjectFactory class or the package name of the generated model to ensure the ObjectFactory class is processed.
If you specify the namespace property on the #XmlElementRef annotation things should work.

jaxb unmarshall child #XmlIDREF

I have class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "customerOrder", propOrder = {
"demandsUuid",
"invoicesOutUuid",
"paymentsUuid",
"customerOrderPosition",
"purchaseOrdersUuid"
})
public class CustomerOrder extends LegendEntity {
#XmlAttribute(name = "sourceAgentUuid")
#XmlIDREF
#XmlSchemaType(name = "IDREF")
#XmlJavaTypeAdapter(XmlAdapterTest.class)
protected Object sourceAgentUuid;
....
Also Agent class for sourceAgentUuid field
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "agent", propOrder = {
"attribute",
"requisite",
"contact",
"contactPerson",
"agentNewsItem",
"tags"
})
#XmlSeeAlso({
Company.class
})
public class Agent
extends LegendEntity
{
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
#XmlID
#XmlSchemaType(name = "ID")
protected String uuid;
And unmarshalling xml snipetpets
<?xml version="1.0" encoding="UTF-8"?>
<customerOrder deliveryPlannedMoment="2014-04-23T16:10:00+04:00" reservedSum="0.0" stateUuid="44b3fca5-a2b3-11e3-31b2-002590a28eca" targetAgentUuid="9a3c7d6b-4245-11e3-24c6-7054d21a8d1e"
sourceAgentUuid="ef0b03de-c95b-11e3-9183-002590a28eca" sourceStoreUuid="b05ed064-8743-11e3-0c1a-002590a28eca"
applicable="true" moment="2014-04-21T17:50:00+04:00" payerVat="true" rate="1.0" vatIncluded="true" created="2014-04-21T17:50:44.142+04:00" createdBy="it#erms" name="440" updated="2014-04-22T12:19:56.472+04:00" updatedBy="it#erms" readMode="SELF" changeMode="NONE">
<accountUuid>5f65cc9e-3708-11e3-bf9a-7054d21a8d1e</accountUuid>
<accountId>5f65cc9e-3708-11e3-bf9a-7054d21a8d1e</accountId>
<uuid>ef1267b8-c95b-11e3-aeb4-002590a28eca</uuid>
<groupUuid>9a3ad96b-4245-11e3-010e-7054d21a8d1e</groupUuid>
<groupId>9a3ad96b-4245-11e3-010e-7054d21a8d1e</groupId>
<code>440</code>
<externalcode>440</externalcode>
When I try to unmarshall
JAXBElement poe = (JAXBElement)u.unmarshal( new FileInputStream( "org_order.xml" ) );
CustomerOrder co=(CustomerOrder)poe.getValue();
System.out.println(co.getSourceAgentUuid());
result null (but all other not #XmlIDREF field unmarshalled ok)
How I can get ef0b03de-c95b-11e3-9183-002590a28eca result ?
I had create test class for simply.
Why output is null?
import java.io.ByteArrayInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
public class TestMarshall {
public static void main(String[] args) {
try {
// marshal();
unmarshal();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void marshal() throws Exception {
CustomerOrder co = new CustomerOrder();
Agent a = new Agent();
a.setUuid("sdfsdf");
co.setSourceAgentUuid(a);
JAXBContext jc = JAXBContext.newInstance(CustomerOrder.class,
Agent.class);
Marshaller m = jc.createMarshaller();
m.marshal(co, System.out);
}
public static void unmarshal() throws Exception {
JAXBContext jc = JAXBContext.newInstance(CustomerOrder.class,
Agent.class);
Unmarshaller u = jc.createUnmarshaller();
String testXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><customerOrder sourceAgentUuid=\"sdfsdf\"/>";
CustomerOrder poe = (CustomerOrder) u
.unmarshal(new ByteArrayInputStream(testXML.getBytes()));
CustomerOrder co = poe;
System.out.println("sourceAgentUuid= " + co.getSourceAgentUuid());
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "agent")
class Agent {
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
#XmlID
#XmlSchemaType(name = "ID")
protected String uuid;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement
#XmlType(name = "customerOrder")
class CustomerOrder {
#XmlAttribute(name = "sourceAgentUuid")
#XmlIDREF
#XmlSchemaType(name = "IDREF")
protected Object sourceAgentUuid;
public Object getSourceAgentUuid() {
return sourceAgentUuid;
}
public void setSourceAgentUuid(Object sourceAgentUuid) {
this.sourceAgentUuid = sourceAgentUuid;
}
}
An #XmlIDREF plus its counterpart #XmlID are "XMLized pointers" that appear as strings in the XML text. JAXB matches such value pairs and resolves matching references into nice object references.
So, after unmarshalling, you won't see the strings from the XML file; the
Object sourceAgentUuid
(in your case) will either contain a reference to that "source agent" object (if there is such an XML element with its #XmlID set to that value) or null otherwise.

JAVA-JAXB/ define class as field

I'm using jaxb, and as I understood, we define for each element and attribute field, and jaxb reconize this attribute, and put it value into this elemnt. My problem that one of my attribute is class:
<div class="hello"> Hi </div>
so I want to define in the class div, the next:
String class;
public String getClass() {
return class;
}
#XmlAttribute
public void setClass(String class) {
this.class = class;
}
But I can't because - Syntax error on token "class", invalid VariableDeclarator
What can I do?
You can use the name property of XmlAttribute to specify a different name for the mapping variable.
String className;
public String getClassName() {
return clazz;
}
#XmlAttribute(name="class")
public void setClassName(String className) {
this.className = className;
}
It is working perfectly fine
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
public class Test {
public static void main(String[] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(Div.class);
Div div = new Div();
div.setClassName("new-item");
StringWriter sw = new StringWriter();
context.createMarshaller().marshal(div, sw);
System.out.println(sw.toString());
String s = "<div class=\"hello\"> Hi </div>";
Div object = (Div) context.createUnmarshaller().unmarshal(new StringReader(s));
System.out.println(object.getClassName());
}
#XmlType(name = "div")
#XmlRootElement(name = "div")
public static class Div {
private String className;
#XmlAttribute(name = "class")
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
}

Categories