I am having issue while unmarshalling an XML message. However, marshaling works fine. I am using inheritance via XML class extractor annotation.
Can you please help me identify the issue here?
Exception:
Caused by: Exception [EclipseLink-44] (Eclipse Persistence Services - 2.7.3.v20180807-4be1041): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class indicator field from database row [org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl#631330c].
Descriptor: XMLDescriptor(main.TransitionGuard --> [])
at org.eclipse.persistence.exceptions.DescriptorException.missingClassIndicatorField(DescriptorException.java:961)
at org.eclipse.persistence.internal.oxm.XMLRelationshipMappingNodeValue.processChild(XMLRelationshipMappingNodeValue.java:85)
at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.startElement(XMLCompositeObjectMappingNodeValue.java:385)
at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startElement(UnmarshalRecordImpl.java:864)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parseEvent(XMLStreamReaderReader.java:138)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:102)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:89)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:940)
at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:637)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:216)
... 1 more
Here are my classes:
Transition
public class Transition {
private String from;
private String to;
TransitionGuard guard;
public Transition() {
// For Moxy
}
public Transition(String from, String to) {
this(from, to, null);
}
public Transition(String from, String to, TransitionGuard guard) {
setFrom(from);
setTo(to);
setTransitionGuard(guard);
}
#XmlAttribute(name = "from")
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
#XmlAttribute(name = "to")
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
#XmlElement(name = "guard")
public TransitionGuard getTransitionGuard() {
return guard;
}
public void setTransitionGuard(TransitionGuard guard) {
this.guard = guard;
}
}
TransitionGuard
#XmlClassExtractor(TransitionGuardClassExtractor.class)
#XmlSeeAlso({ ExceptionGuard.class, ScriptedGuard.class })
public abstract class TransitionGuard {
}
TransitionGuardClassExtractor
public class TransitionGuardClassExtractor extends ClassExtractor {
#Override
public Class extractClassFromRow(Record record, Session session) {
if (null != record.get("/abpm:exception-guard")) {
return ExceptionGuard.class;
} else if (null != record.get("/abpm:scripted-guard")) {
return ScriptedGuard.class;
}
return null;
}
}
ScriptedGuard
public class ScriptedGuard extends TransitionGuard {
String script;
public ScriptedGuard() {
}
public ScriptedGuard(String script) {
setScript(script);
}
#XmlPath("abpm:scripted-guard/text()")
#XmlCDATA
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
}
TestPE
#XmlRootElement(name = "TestPE")
public class TestPE {
List<Transition> transition;
public List<Transition> getTransition() {
return transition;
}
public void setTransition(List<Transition> transition) {
this.transition = transition;
}
}
package-info
#XmlSchema(namespace = "jelly:com.werken.blissed.jelly.BlissedTagLibrary", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {
#XmlNs(prefix = "version", namespaceURI = "4.7"), #XmlNs(prefix = "j", namespaceURI = "jelly:core"),
#XmlNs(prefix = "abpm", namespaceURI = "jelly:com.adeptia.indigo.jelly.IndigoTagLibrary"),
#XmlNs(prefix = "pd", namespaceURI = "jelly:com.adeptia.indigo.pd.ProcessDesignerTagLibrary"),
#XmlNs(prefix = "", namespaceURI = "jelly:com.werken.blissed.jelly.BlissedTagLibrary") })
package main;
import javax.xml.bind.annotation.XmlNs;
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<TestPE xmlns:version = "4.7" xmlns:j = "jelly:core" xmlns:abpm = "jelly:com.adeptia.indigo.jelly.IndigoTagLibrary" xmlns:pd = "jelly:com.adeptia.indigo.pd.ProcessDesignerTagLibrary" xmlns = "jelly:com.werken.blissed.jelly.BlissedTagLibrary" >
<transition from="state-BPMN:GATEWAY:XOR_DATA_GATEWAY-892276265" to="state-BPMN:EVENT:END_EVENT-892276264" >
<guard>
<abpm:scripted-guard><![CDATA[*** Script ***]]></abpm:scripted-guard>
</guard>
</transition>
</TestPE>
Demo code
Map<String, String> properties = new HashMap<String, String>();
properties.put("javax.xml.bind.context.factory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
JAXBContext jc = JAXBContext.newInstance(new Class[] { TestPE.class }, properties);
// JAXB unmarshall
Unmarshaller unmarshaller = jc.createUnmarshaller();
TestPE testPE = (TestPE) unmarshaller.unmarshal(new File("resources/Transition.xml"));
Currently, MOXy requires that the inheritance indicator is in an XML attribute. If it is in an XML element you could use the following approach with an XmlAdapter.
Related
Hi I got a below XML string which contain diffgram
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Result xmlns="">
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet xmlns="">
<DT1 diffgr:id="DT11" msdata:rowOrder="0">
<TEST_NO>93481324345</TEST_NO>
<TEST_DESC>Description1</TEST_DESC>
</DT1>
<DT1 diffgr:id="DT12" msdata:rowOrder="1">
<TEST_NO>93481366454</TEST_NO>
<TEST_DESC>Description2</TEST_DESC>
</DT1>
<DT1 diffgr:id="DT13" msdata:rowOrder="2">
<TEST_NO>934813267783</TEST_NO>
<TEST_DESC>Description3</TEST_DESC>
</DT1>
</NewDataSet>
</diffgr:diffgram>
</Result>
How can I unmarshal this String to java POJO using JAXB ?
Below are the current POJO seems not able to bind by this way.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"diffgr",
"newDataSet",
"dt"
})
#XmlRootElement(name="Result")
public class Response {
#XmlElement(name = "diffgr:diffgram")
protected String diffgr;
#XmlElement(name = "NewDataSet")
protected String newDataSet;
#XmlElement(name = "DT1")
protected List<Response.DT> dt;
public String getDiffgr() {
return diffgr;
}
public void setDiffgr(String diffgr) {
this.diffgr = diffgr;
}
public String getNewDataSet() {
return newDataSet;
}
public void setNewDataSet(String newDataSet) {
this.newDataSet = newDataSet;
}
public List<Response.DT> getDt() {
if (dt == null) {
dt = new ArrayList<Response.DT>();
}
return this.dt;
}
public void setDt(List<Response.DT> dt) {
this.dt = dt;
}
#Override
public String toString() {
return "Response [diffgr=" + diffgr + ", newDataSet=" + newDataSet + ", dt=" + dt + "]";
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"testNo",
"testDesc"
})
public static class DT {
#XmlElement(name = "TEST_NO")
protected String testNo;
#XmlElement(name = "TEST_DESC")
protected String testDesc;
public String getTestNo() {
return testNo;
}
public void setTestNo(String testNo) {
this.testNo = testNo;
}
public String getTestDesc() {
return testDesc;
}
public void setTestDesc(String testDesc) {
this.testDesc = testDesc;
}
#Override
public String toString() {
return "DT [testNo=" + testNo + ", testDesc=" + testDesc + "]";
}
}
}
I'm using the below sample code to unmarshal the String
JAXBContext jaxbContext = JAXBContext.newInstance(Response.class);
Unmarshaller jaxbUnMarshaller = jaxbContext.createUnmarshaller();
Response response = (Response)jaxbUnMarshaller.unmarshal(new StringReader(xml));
When execute there is no any error throwing out while the POJO was empty.
How to unmarshal an XML String contain diffgr to JAVA POJO like this case?
I have an element "SubElement2" that has value and attribute.
Working :
My Annotation are
#XmlValue
#JsonProperty(value="content")
private String value;
Request in XML : <SubElement2 parameterName = "tested">ELEMENT_2_TAG_VAL</SubElement2>
TO JSON :
{
"SubElement2" : {
"content" : "ELEMENT_2_TAG_VAL",
"parameterName" : "tested"
}
}
Here I want to change the property name content to myOwnContent
Not Working:
Modified annotations :
#XmlValue
#JsonProperty(value="myOwnContent") // Modified
private String value;
Request in XML : <SubElement2 parameterName = "tested">ELEMENT_2_TAG_VAL</SubElement2>
For the above annotation change, I'm facing below exception:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "content" (class SubElement2), not marked as ignorable (2 known properties: "parameterName", "myOwnContent"])
at [Source: (String)"{"SubElement2":{"parameterName":"tested","content":"ELEMENT_2_TAG_VAL"}}"; line: 1, column: 53] (through reference chain: Element1["SubElement2"]->SubElement2["content"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:60)
Below is my code :
ObjectFactory.java
#XmlRegistry
public class ObjectFactory {
public SubElement2 createSubElement2() {
return new SubElement2();
}
}
MainProgram.java
public class MainProgram {
public static void main(String[] args) throws ClassNotFoundException, IOException {
String request = "<SubElement2 parameterName = \"tested\">ELEMENT_2_TAG_VAL</SubElement2>";
System.out.println("Request in XML : "+request);
JSONObject jObject = XML.toJSONObject(request);
ObjectMapper mapper = createCombinedObjectMapper();
Object json = mapper.readValue(jObject.toString(), Class.forName("Element1"));
String output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
System.out.println(output);
}
private static ObjectMapper createCombinedObjectMapper() {
return new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, false)
.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.setAnnotationIntrospector(createJaxbJacksonAnnotationIntrospector());
}
private static AnnotationIntrospector createJaxbJacksonAnnotationIntrospector() {
final AnnotationIntrospector jaxbIntrospector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
final AnnotationIntrospector jacksonIntrospector = new JacksonAnnotationIntrospector();
return AnnotationIntrospector.pair(jacksonIntrospector, jaxbIntrospector);
}
}
SubElement2.java
#XmlRootElement(name = "SubElement2")
public class SubElement2 {
#XmlValue
#JsonProperty(value="myOwnContent")
private String value;
#JsonProperty(value="parameterName",required=true)
#XmlAttribute(required = true)
protected String parameterName;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getParameterName() {
return parameterName;
}
public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}
}
Element1.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "element1", propOrder = {
"element1"
})
#XmlRootElement(name = "Element1")
public class Element1 {
#XmlElement(name="SubElement2")
protected SubElement2 subElement2;
public SubElement2 getSubElement2() {
return subElement2;
}
public void setSubElement2(SubElement2 subElement2) {
this.subElement2 = subElement2;
}
}
I'm using Jackson version : 2.9.7
Help me to solve this exception ,thanks in advance
What I want to do :
I want to have jsonproperty as myOwnContent because content is already used by another attribute in XML in my existing implementation. (Existing implementation doesn't have JSON suuport , we are adding JSON support)
I work with a SOAP web service. I want to recover the list productOrder from a java. My problem is that the list productOrder recovered from the java class is zero.
I dont't know how to recover this list from the java.
Below I explain my classes:
This is the request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://uciext.ws.hw3/wsdl">
<soapenv:Header/>
<soapenv:Body>
<wsdl:processOrder>
<!--Optional:-->
<arg0>
<vendorCode>330029</vendorCode>
<vendorName>My Shop</vendorName>
<orderNumber>1000339</orderNumber>
<!--1 or more repetitions:-->
<wsdl:productOrder>
<!--Optional:-->
<productSku>111</productSku>
<!--Optional:-->
<productName>Kindle Fire</productName>
<!--Optional:-->
<orderQuantity>5</orderQuantity>
</wsdl:productOrder>
</arg0>
</wsdl:processOrder>
</soapenv:Body>
</soapenv:Envelope>
I have the Order.java to parse this xml
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"vendorCode",
"vendorName",
"orderNumber",
"productOrder"
})
#XmlRootElement(name = "order")
public class Order {
#XmlElement(required = true)
protected String vendorCode;
#XmlElement(required = true)
protected String vendorName;
#XmlElement(required = true)
protected String orderNumber;
#XmlElement(required = true)
protected List<ProductOrder> productOrder;
public String getVendorCode() {
return vendorCode;
}
public void setVendorCode(String value) {
this.vendorCode = value;
}
public String getVendorName() {
return vendorName;
}
public void setVendorName(String value) {
this.vendorName = value;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String value) {
this.orderNumber = value;
}
public List<ProductOrder> getProductOrder() {
if (productOrder == null) {
productOrder = new ArrayList<ProductOrder>();
}
return this.productOrder;
}
}
I have a method processOrder in a interface and their implementation. This
is the interface
#WebService(targetNamespace = "http://uciext.ws.hw3/wsdl")
public interface OrderServiceWS {
#WebMethod
OrderConfirm processOrder(#WebParam(name="arg0", mode=Mode.IN) Order order) throws Exception;
}
processOrder is in the class
#XmlRootElement(name = "processOrder", namespace = "http://uciext.ws.hw3/wsdl")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "processOrder", namespace = "http://uciext.ws.hw3/wsdl")
public class ProcessOrder {
#XmlElement(name = "arg0", namespace = "")
private com.uciext.ws.hw3.service.model.order.Order arg0;
public com.uciext.ws.hw3.service.model.order.Order getArg0() {
return this.arg0;
}
public void setArg0(com.uciext.ws.hw3.service.model.order.Order arg0) {
this.arg0 = arg0;
}
}
This is the interface implementation where is called the method processOrder.
#WebService(
portName = "OrderPort",
serviceName = "OrderService",
targetNamespace = "http://uciext.ws.hw3/wsdl",
endpointInterface = "com.uciext.ws.hw3.service.OrderServiceWS")
public class OrderServiceWSImpl implements OrderServiceWS {
private InventoryManagerImpl manager = new InventoryManagerImpl();
#Override
public OrderConfirm processOrder(Order order) throws Exception {
Util.log("SOAP processOrder request [ order=" + order);
Util.log("OrderServiceWS start processOrder");
OrderDAO orderDAO = new OrderDAO();
List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
List<ProductOrderDAO> productOrderDAOList = new ArrayList<ProductOrderDAO>();
ProductOrderDAO productOrderDAO1 = null;
ProductDAO productDAO = null;
OrderConfirm orderConfirm = null;
ProductOrder productOrder = null;
ProductConfirm productConfirm = null;
List<ProductConfirm> productConfirmList = new ArrayList<ProductConfirm>();
Double totalPrice = 0.0;
Util.log("OrderServiceWS start processOrder vendorCode "+order.getVendorCode());
orderDAO.setVendorCode(order.getVendorCode());
orderDAO.setVendorName(order.getVendorName());
orderDAO.setOrderId(Long.parseLong(order.getOrderNumber()));
Util.log("OrderServiceWS processOrder before productOrderList ");
productOrderList = order.getProductOrder();
Util.log("OrderServiceWS processOrder before productOrderList size "+productOrderList.size());
The value of vendorCode is right but productOrderList.size() is cero
From an XQuery performed by BaseX server I get a result like that:
<ProtocolloList>
<protocollo>
<numero>1</numero>
<data>2014-06-23</data>
<oggetto/>
<destinatario/>
<operatore/>
</protocollo>
...
</ProtocolloList>
And I need to convert this result in a List of Protocollo objects with JAXB so that I can show them with JList. Thus, following one of the discussions here I've declared the following classes:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "protocollo")
public class Protocollo {
private int numero;
private String data;
private String oggetto;
private String destinatario;
private String operatore;
public Protocollo(String d, String o, String des, String op) {
this.data = d;
this.oggetto = o;
this.destinatario = des;
this.operatore = op;
}
public Protocollo() {
}
#XmlElement
public int getNumero() {
return numero;
}
public void setNumero(int numero) {
this.numero = numero;
}
#XmlElement
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
#XmlElement
public String getOggetto() {
return oggetto;
}
public void setOggetto(String oggetto) {
this.oggetto = oggetto;
}
#XmlElement
public String getDestinatario() {
return destinatario;
}
public void setDestinatario(String destinatario) {
this.destinatario = destinatario;
}
#XmlElement
public String getOperatore() {
return operatore;
}
public void setOperatore(String operatore) {
this.operatore = operatore;
}
}
and
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "ProtocolloList")
public class ProtocolloList {
#XmlElementWrapper(name = "ProtocolloList")
#XmlElement(name = "protocollo")
private ArrayList<Protocollo> ProtocolloList;
public ArrayList<Protocollo> getProtocolloList() {
return ProtocolloList;
}
public void setProtocolloList(ArrayList<Protocollo> protocolloList) {
ProtocolloList = protocolloList;
}
}
and finally I execute the converion like that:
JAXBContext jaxbContext = JAXBContext.newInstance(Protocollo.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(this.resultXML);
protocolli = (ProtocolloList) unmarshaller.unmarshal(reader);
And I keep on getting this exception:
unexpected element (uri:"", local:"ProtocolloList"). Expected elements are <{}protocollo>
I suppose I'm making some mistakes with annotations.
Can you help?
For your use case you do not need the #XmlElementWrapper annotation. This is because the ProtocolList element corresponds to your #XmlRootElement annotation. Then you need the #XmlElement annotation on the property to grab each of the list items.
#XmlRootElement(name = "ProtocolloList")
public class ProtocolloList {
private ArrayList<Protocollo> ProtocolloList;
#XmlElement(name = "protocollo")
public ArrayList<Protocollo> getProtocolloList() {
return ProtocolloList;
}
}
Note:
By default you should annotate the property. If you want to annotate the fields you should put #XmlAccessorType(XmlAccessType.FIELD) on your class.
UPDATE
You need to make sure your JAXBContext is aware of the root class. You can change your JAXBContext creation code to be the following:
JAXBContext jaxbContext = JAXBContext.newInstance(ProtocolloList.class);
How would I map this
<urn:envelope xmlns:urn="urn:com.twinstrata.webservice:2.1">
<urn:encoded>
<urn:response>
<urn:license>
<urn:licenseTag>WHATEVER934</urn:licenseTag>
<urn:accountNumber>2016763117</urn:accountNumber>
<urn:licenseType>TRIAL</urn:licenseType>
<urn:licenseClass>Credentialed</urn:licenseClass>
<urn:volumeAllowed>Unlimited</urn:volumeAllowed>
<urn:volumeProvisioned>0</urn:volumeProvisioned>
<urn:snapshotLimit>Unlimited</urn:snapshotLimit>
<urn:snapshotLimitPerVolume>10</urn:snapshotLimitPerVolume>
<urn:status>Active</urn:status>
<urn:usedSpace>0</urn:usedSpace>
<urn:expirtationDate>2013-03-27 14:48:47.0</urn:expirtationDate>
<urn:storageLimit>Unlimited</urn:storageLimit>
</urn:license>
</urn:response>
</urn:encoded>
<urn:signature>Hl8rk2aTEsOkkq5e383LH0BqdFfmVcKIg9FuFEnnrlFk9fwYVEQwkrm/7MPM2Zmli2Um00L2Ab25tZg2w8pEzXyDsd+vwCAH0ypQwhIVPayDjgYKlYXbnkqG5S+7qiVbqD2qZDektuPoEWvaSdxO3ZgUibT+nnrO0kl6E7i4lB0=
</urn:signature>
to this
package com.folio3.bean;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "envelope" , namespace = "urn:com.twinstrata.webservice:2.1")
public class ResponseXML {
private String userName;
private String license;
private String signature;
private String licenseTag;
private String accountNumber;
private String licenseType;
private String licenseClass;
private String volumeAllowed;
private String volumeProvisioned;
private String publicKey;
#XmlElement(name = "userName" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
#XmlElement(name = "license" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
#XmlElement(name = "signature" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
#XmlElement(name = "licenseTag" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicenseTag() {
return licenseTag;
}
public void setLicenseTag(String licenseTag) {
this.licenseTag = licenseTag;
}
#XmlElement(name = "accountNumber" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
#XmlElement(name = "licenseType" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicenseType() {
return licenseType;
}
public void setLicenseType(String licenseType) {
this.licenseType = licenseType;
}
#XmlElement(name = "licenseClass" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicenseClass() {
return licenseClass;
}
public void setLicenseClass(String licenseClass) {
this.licenseClass = licenseClass;
}
#XmlElement(name = "volumeAllowed" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getVolumeAllowed() {
return volumeAllowed;
}
public void setVolumeAllowed(String volumeAllowed) {
this.volumeAllowed = volumeAllowed;
}
#XmlElement(name = "volumeProvisioned" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getVolumeProvisioned() {
return volumeProvisioned;
}
public void setVolumeProvisioned(String volumeProvisioned) {
this.volumeProvisioned = volumeProvisioned;
}
#XmlElement(name = "publicKey" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ResponseXML [userName=");
builder.append(userName);
builder.append(", license=");
builder.append(license);
builder.append(", signature=");
builder.append(signature);
builder.append(", licenseTag=");
builder.append(licenseTag);
builder.append(", accountNumber=");
builder.append(accountNumber);
builder.append(", licenseType=");
builder.append(licenseType);
builder.append(", licenseClass=");
builder.append(licenseClass);
builder.append(", volumeAllowed=");
builder.append(volumeAllowed);
builder.append(", volumeProvisioned=");
builder.append(volumeProvisioned);
builder.append(", publicKey=");
builder.append(publicKey);
builder.append("]");
return builder.toString();
}
}
Currently , It maps only one property of XML , that is "signature".
For the sake of simplicity, I don't want to make other classes and nest the objects inside it. I just want to parse nested xml tags in single Java class.
How do I do that ?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
ResponseXML
You could use MOXy's #XmlPathextension to map your use case (see: http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html). Below is a partial mapping of your use case.
package forum15391077;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement(name = "envelope")
#XmlType(propOrder={"licenseTag", "accountNumber", "licenseType", "licenseClass", "volumeAllowed", "volumeProvisioned", "signature", "license", "publicKey", "userName"})
#XmlAccessorType(XmlAccessType.FIELD)
public class ResponseXML {
private String userName;
private String license;
private String signature;
#XmlPath("urn:encoded/urn:response/urn:license/urn:licenseTag/text()")
private String licenseTag;
#XmlPath("urn:encoded/urn:response/urn:license/urn:accountNumber/text()")
private String accountNumber;
#XmlPath("urn:encoded/urn:response/urn:license/urn:licenseType/text()")
private String licenseType;
#XmlPath("urn:encoded/urn:response/urn:license/urn:licenseClass/text()")
private String licenseClass;
#XmlPath("urn:encoded/urn:response/urn:license/urn:volumeAllowed/text()")
private String volumeAllowed;
#XmlPath("urn:encoded/urn:response/urn:license/urn:volumeProvisioned/text()")
private String volumeProvisioned;
private String publicKey;
}
package-info
We will use the package level #XmlSchema annotation to specify the namespace qualification (see: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html). We will also use it to define the urn prefix which we leveraged in the #XmlPath annotation.
#XmlSchema(
namespace="urn:com.twinstrata.webservice:2.1",
elementFormDefault=XmlNsForm.QUALIFIED,
xmlns={
#XmlNs(namespaceURI = "urn:com.twinstrata.webservice:2.1", prefix = "urn")
}
)
package forum15391077;
import javax.xml.bind.annotation.*;
jaxb.properties
To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
Since MOXy is a standard JAXB implementation, the standard JAXB runtime APIs are used.
package forum15391077;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(ResponseXML.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum15391077/input.xml");
ResponseXML response = (ResponseXML) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
}
input.xml/Output
Below is a sample XML document based on the part of your use case that I mapped.
<?xml version="1.0" encoding="UTF-8"?>
<urn:envelope xmlns:urn="urn:com.twinstrata.webservice:2.1">
<urn:encoded>
<urn:response>
<urn:license>
<urn:licenseTag>WHATEVER934</urn:licenseTag>
<urn:accountNumber>2016763117</urn:accountNumber>
<urn:licenseType>TRIAL</urn:licenseType>
<urn:licenseClass>Credentialed</urn:licenseClass>
<urn:volumeAllowed>Unlimited</urn:volumeAllowed>
<urn:volumeProvisioned>0</urn:volumeProvisioned>
</urn:license>
</urn:response>
</urn:encoded>
<urn:signature>Hl8rk2aTEsOkkq5e383LH0BqdFfmVcKIg9FuFEnnrlFk9fwYVEQwkrm/7MPM2Zmli2Um00L2Ab25tZg2w8pEzXyDsd+vwCAH0ypQwhIVPayDjgYKlYXbnkqG5S+7qiVbqD2qZDektuPoEWvaSdxO3ZgUibT+nnrO0kl6E7i4lB0=
</urn:signature>
</urn:envelope>
I made it working by creating nested classes and by using proper JAXB annotations.