I'm trying to unmarshall XML to POJO VmML class to pass it throught our system. The POJO classes was created from dtd file using jaxb2 maven plugin. When I use feature camel-jaxb in karaf I was able to unmarshall XML file into object of class VmML without any problem, but for some reasons I have to pull back this approach, and finally I end up with camel-jacksonxml.
In the route now I'm using unmarshall tag as below.
<dataFormats>
<jacksonxml id="jack" unmarshalTypeName="com.company.generated.VmML"/>
</dataFormats>
<rest path="/service"
consumes="application/xml"
produces="text/plain">
<post uri="/requestXmlCfg"
type="com.company.generated.VmML"
outType="java.lang.String">
<route>
<unmarshal ref="jack"/>
<to uri="bean:messageProcessot?method=process"/>
</route>
</post>
</rest>
I want to emphasize that it works earlier without unmarshaling tag, when I use simple camel-jaxb feature.
Now I get the exception which appears here often, but in my case the solutions are not proper because the data is provided and I don't want to skip anything. The error is:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ReportType" (class com.company.generated.CarrierReport), not marked as ignorable (3 known properties: "CarrierReportSnapshot", "CarrierReportHeader", "CarrierReportPeriod"])
at [Source: org.apache.camel.component.netty4.http.NettyChannelBufferStreamCache#612e834b; line: 6, column: 42] (through reference chain: com.company.generated.VmML["CarrierReport"]->java.util.ArrayList[0]->com.company.generated.CarrierReport["ReportType"])
POJO classes was created bas on: http://www.vmml.org/spec/VmML_v0.1.dtd
And the XML is filled properly
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE VmML SYSTEM "http://www.vmml.org/spec/VmML_v0.1.dtd">
<VmML Version="0.1">
<CarrierReport>
<CarrierReportHeader>
<ReportType SystemReference="aa">VMML</ReportType>
<ReportTimestamp Timezone="0" TimeFormat="RFC822">Tue, 07 May 2013 15:21:14 %2B0000</ReportTimestamp>
<SenderId SystemReference="aa">aa</SenderId>
<ReceiverId SystemReference="aa">aa</ReceiverId>
<SystemSource>aa</SystemSource>
<SystemDestination>aa</SystemDestination>
</CarrierReportHeader>
<CarrierReportSnapshot>
<Event>
<EventHeader>
<EventTimestamp Timezone="0" TimeFormat="RFC822">Tue, 07 May 2013 15:21:14 %2B0000</EventTimestamp>
<EventCode SystemReference="aa">aa</EventCode>
<EventText>aa</EventText>
</EventHeader>
</Event>
</CarrierReportSnapshot>
</CarrierReport>
</VmML>
VMML class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"carrierReport"
})
#XmlRootElement(name = "VmML")
public class VmML {
#XmlAttribute(name = "Version", required = true)
#XmlJavaTypeAdapter(NormalizedStringAdapter.class)
protected String version;
#XmlAttribute(name = "id")
#XmlJavaTypeAdapter(NormalizedStringAdapter.class)
protected String id;
#XmlElement(name = "CarrierReport", required = true)
protected List<CarrierReport> carrierReport;
public String getVersion() {
return version;
}
public void setVersion(String value) {
this.version = value;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
public List<CarrierReport> getCarrierReport() {
if (carrierReport == null) {
carrierReport = new ArrayList<CarrierReport>();
}
return this.carrierReport;
}
}
CarrierReport class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"carrierReportHeader",
"carrierReportSnapshot",
"carrierReportPeriod"
})
#XmlRootElement(name = "CarrierReport")
public class CarrierReport {
#XmlElement(name = "CarrierReportHeader", required = true)
protected CarrierReportHeader carrierReportHeader;
#XmlElement(name = "CarrierReportSnapshot")
protected CarrierReportSnapshot carrierReportSnapshot;
#XmlElement(name = "CarrierReportPeriod")
protected CarrierReportPeriod carrierReportPeriod;
public CarrierReportHeader getCarrierReportHeader() {
return carrierReportHeader;
}
public void setCarrierReportHeader(CarrierReportHeader value) {
this.carrierReportHeader = value;
}
public CarrierReportSnapshot getCarrierReportSnapshot() {
return carrierReportSnapshot;
}
public void setCarrierReportSnapshot(CarrierReportSnapshot value) {
this.carrierReportSnapshot = value;
}
public CarrierReportPeriod getCarrierReportPeriod() {
return carrierReportPeriod;
}
public void setCarrierReportPeriod(CarrierReportPeriod value) {
this.carrierReportPeriod = value;
}
}
ReportType
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"value"
})
#XmlRootElement(name = "ReportType")
public class ReportType {
#XmlAttribute(name = "SystemReference")
#XmlJavaTypeAdapter(NormalizedStringAdapter.class)
protected String systemReference;
#XmlValue
protected String value;
public String getSystemReference() {
return systemReference;
}
public void setSystemReference(String value) {
this.systemReference = value;
}
public String getvalue() {
return value;
}
public void setvalue(String value) {
this.value = value;
}
}
Vmml > Carier Report > Carier Report Header > ReportType class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"reportType",
"reportTimestamp",
"senderId",
"receiverId",
"systemSource",
"systemDestination",
"missionId",
"missionName"
})
#XmlRootElement(name = "CarrierReportHeader")
public class CarrierReportHeader {
#XmlElement(name = "ReportType", required = true)
protected ReportType reportType;
#XmlElement(name = "ReportTimestamp", required = true)
protected ReportTimestamp reportTimestamp;
#XmlElement(name = "SenderId", required = true)
protected SenderId senderId;
#XmlElement(name = "ReceiverId")
protected ReceiverId receiverId;
#XmlElement(name = "SystemSource", required = true)
protected String systemSource;
#XmlElement(name = "SystemDestination")
protected String systemDestination;
#XmlElement(name = "MissionId")
protected MissionId missionId;
#XmlElement(name = "MissionName")
protected String missionName;
public ReportType getReportType() {
return reportType;
}
public void setReportType(ReportType value) {
this.reportType = value;
}
public ReportTimestamp getReportTimestamp() {
return reportTimestamp;
}
public void setReportTimestamp(ReportTimestamp value) {
this.reportTimestamp = value;
}
public SenderId getSenderId() {
return senderId;
}
public void setSenderId(SenderId value) {
this.senderId = value;
}
public ReceiverId getReceiverId() {
return receiverId;
}
public void setReceiverId(ReceiverId value) {
this.receiverId = value;
}
public String getSystemSource() {
return systemSource;
}
public void setSystemSource(String value) {
this.systemSource = value;
}
public String getSystemDestination() {
return systemDestination;
}
public void setSystemDestination(String value) {
this.systemDestination = value;
}
public MissionId getMissionId() {
return missionId;
}
public void setMissionId(MissionId value) {
this.missionId = value;
}
public String getMissionName() {
return missionName;
}
public void setMissionName(String value) {
this.missionName = value;
}
}
Related
Java 1.8
Maven snippet:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.2</version>
</dependency>
snipped.xml
<?xml version="1.0" standalone="no"?>
<ledesxml_snipped>
<lede_name>Fitzhume</lede_name>
<firm>
<lf_tax_id>999999999</lf_tax_id>
<lf_id>Cogswell Cogs</lf_id>
<lf_name>Cogswell Cogs, Inc.</lf_name>
<lf_address>
<address_info>
<address_1>404 Asteroid Drive</address_1>
<address_3>Suite 2600</address_3>
<city>Dallas</city>
<state_province>TX</state_province>
<zip_postal_code>75203</zip_postal_code>
<country>USA</country>
</address_info>
</lf_address>
<lf_billing_contact_phone>2145551212</lf_billing_contact_phone>
<lf_billing_contact_fax>2148761234</lf_billing_contact_fax>
<lf_billing_contact_email>bigcog#cogswellcogs.com</lf_billing_contact_email>
<source_app>AimPoint</source_app>
<app_version>
</app_version>
</firm>
</ledesxml_snipped>
LedesSnipped.java
package com.my.application.model;
import java.io.*;
import java.util.*;
import javax.xml.bind.annotation.*;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"ledeName",
"firm"
})
#XmlRootElement(name = "ledesxml_snipped")
public class LedesxmlSnipped {
#XmlElement(name = "lede_name", required = true)
protected String ledeName;
#XmlElement(required = true)
#JacksonXmlElementWrapper( useWrapping = false)
protected LedesxmlSnipped.Firm firm;
public String getLedeName() {
return ledeName;
}
public void setLedName( String ledeName) {
this.ledeName = ledeName;
}
public LedesxmlSnipped.Firm getFirm() {
return firm;
}
public void setFirm(LedesxmlSnipped.Firm value) {
this.firm = value;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"lfTaxId",
"lfId",
"lfName",
"lfAddress",
"lfBillingContactPhone",
"lfBillingContactFax",
"lfBillingContactEmail",
"sourceApp",
"appVersion"
})
public static class Firm {
#XmlElement(name = "lf_tax_id")
protected int lfTaxId;
#XmlElement(name = "lf_id", required = true)
protected String lfId;
#XmlElement(name = "lf_name", required = true)
protected String lfName;
#XmlElement(name = "lf_address", required = true)
#JacksonXmlElementWrapper( useWrapping = false)
protected Ledesxml.Firm.LfAddress lfAddress;
#XmlElement(name = "lf_billing_contact_phone")
protected long lfBillingContactPhone;
#XmlElement(name = "lf_billing_contact_fax")
protected long lfBillingContactFax;
#XmlElement(name = "lf_billing_contact_email", required = true)
protected String lfBillingContactEmail;
#XmlElement(name = "source_app", required = true)
protected String sourceApp;
#XmlElement(name = "app_version", required = true)
protected String appVersion;
public int getLfTaxId() {
return lfTaxId;
}
public void setLfTaxId(int value) {
this.lfTaxId = value;
}
public String getLfId() {
return lfId;
}
public void setLfId(String value) {
this.lfId = value;
}
public String getLfName() {
return lfName;
}
public void setLfName(String value) {
this.lfName = value;
}
public Ledesxml.Firm.LfAddress getLfAddress() {
return lfAddress;
}
public void setLfAddress(Ledesxml.Firm.LfAddress value) {
this.lfAddress = value;
}
public long getLfBillingContactPhone() {
return lfBillingContactPhone;
}
public void setLfBillingContactPhone(long value) {
this.lfBillingContactPhone = value;
}
public long getLfBillingContactFax() {
return lfBillingContactFax;
}
public void setLfBillingContactFax(long value) {
this.lfBillingContactFax = value;
}
public String getLfBillingContactEmail() {
return lfBillingContactEmail;
}
public void setLfBillingContactEmail(String value) {
this.lfBillingContactEmail = value;
}
public String getSourceApp() {
return sourceApp;
}
public void setSourceApp(String value) {
this.sourceApp = value;
}
public String getAppVersion() {
return appVersion;
}
public void setAppVersion(String value) {
this.appVersion = value;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"addressInfo"
})
public static class LfAddress {
#XmlElement(name = "address_info", required = true)
protected Ledesxml.Firm.LfAddress.AddressInfo addressInfo;
public Ledesxml.Firm.LfAddress.AddressInfo getAddressInfo() {
return addressInfo;
}
public void setAddressInfo(Ledesxml.Firm.LfAddress.AddressInfo value) {
this.addressInfo = value;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"address1",
"address3",
"city",
"stateProvince",
"zipPostalCode",
"country"
})
public static class AddressInfo {
#XmlElement(name = "address_1", required = true)
protected String address1;
#XmlElement(name = "address_3", required = true)
protected String address3;
#XmlElement(required = true)
protected String city;
#XmlElement(name = "state_province", required = true)
protected String stateProvince;
#XmlElement(name = "zip_postal_code")
protected int zipPostalCode;
#XmlElement(required = true)
protected String country;
public String getAddress1() {
return address1;
}
public void setAddress1(String value) {
this.address1 = value;
}
public String getAddress3() {
return address3;
}
public void setAddress3(String value) {
this.address3 = value;
}
public String getCity() {
return city;
}
public void setCity(String value) {
this.city = value;
}
public String getStateProvince() {
return stateProvince;
}
public void setStateProvince(String value) {
this.stateProvince = value;
}
public int getZipPostalCode() {
return zipPostalCode;
}
public void setZipPostalCode(int value) {
this.zipPostalCode = value;
}
public String getCountry() {
return country;
}
public void setCountry(String value) {
this.country = value;
}
}
}
}
}
and lastly, TryThis.java
package com.my.application;
import java.util.*;
import java.io.*;
import java.time.*;
import java.time.format.*;
import javax.xml.stream.*;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.dataformat.xml.*;
import com.my.application.model.*;
public class TryThis {
public static void main(String[] args) {
XmlMapper mapper = new XmlMapper();
mapper.enable( SerializationFeature.INDENT_OUTPUT);
mapper.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
try {
File innFile = new File("snipped.xml");
LedesxmlSnipped asfda = mapper.readValue(innFile, LedesxmlSnipped.class);
System.out.println( "ledeName=" + asfda.getFirm().getLedeName());
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
the result of all this is just
ledeName=null
where I'd expect to see
ledeName=Fitzhume
No errors. So what am I missing? Some fiendishly subtle configuration? Am I defining XmlMapper in the wrong place? The many examples I've looked at span various versions of Jackson and some go back to using javax.xml.
Simply adding
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
and
mapper.registerModule( new JaxbAnnotationModule());
to TryThis.java did the trick. Fiendishly subtle configuration issue indeed!
Thx to all who read the question.
I'm attempting to parse a generated .xml report from ReadyAPI through unmarshalling but am having trouble building out the classes. My example is much more complex then most of the research I have done online so it is hard for me to compare them. Could anyone help me build the object structure for something like this?
Example.xml
<testSuiteResults>
<testSuite>
<startTime>00:00:00</startTime>
<status>PASS</status>
<testSuiteName>Example Test Suite Name</testSuiteName>
<timeTaken>246</timeTaken>
<testRunnerResults>
<testCase>
<startTime>00:00:00</startTime>
<status>PASS</status>
<testCaseId>111aaa111aaa111aaa111</testCaseId>
<testCaseName>Example TestCase Name</testCaseName>
<timeTaken>123</timeTaken>
<testStepResults>
<result>
<message>Example Message</message>
<name>Example Result Name</name>
<order>1</order>
<started>00:00:00</started>
<status>PASS</status>
<timeTaken>123</timeTaken>
</result>
</testStepResults>
<testStepParameters>
<parameters>
<iconPath>/icon_path.png</iconPath>
<testStepName>Example Test</testStepName>
</parameters>
</testStepParameters>
</failedTestSteps>
</testCase>
<testCase>
<reason>Example Fail Reason</reason>
<startTime>00:00:00</startTime>
<status>FAIL</status>
<testCaseId>123abc123abc123abc123</testCaseId>
<testCaseName>Example Test Case Name 2</testCaseName>
<timeTaken>123</timeTaken>
<testStepResults>
<result>
<message>Example Message 2</message>
<name>Example Test Step Name 2</name>
<order>1</order>
<started>00:00:00</started>
<status>FAIL</status>
<timeTaken>123</timeTaken>
</result>
</testStepResults>
<testStepParameters>
<parameters>
<iconPath>/icon_path_2.png</iconPath>
<testStepName>Example Test Step Name 2</testStepName>
</parameters>
</testStepParameters>
<failedTestSteps>
<error>
<detail>Example Detail</detail>
<icon>icon.png</icon>
<testCaseName>Example Test Case Name 2</testCaseName>
<testStepName>Example Test Step Name 2</testStepName>
<testSuiteName>Example Test Suite Name</testSuiteName>
</error>
</failedTestSteps>
</testCase>
</testRunnerResults>
</testSuite>
</testSuiteResults>
After many iterations I have landed on this structure:
#XmlRootElement(name = "testSuiteResults")
#XmlAccessorType(XmlAccessType.FIELD)
public class TestSuiteResults {
#XmlElement(name = "testSuite")
private List<TestSuite> testSuites;
public void setTestSuites(List<TestSuite> testSuites) {
this.testSuites = testSuites;
}
public List<TestSuite> getTestSuites() {
return this.testSuites;
}
public boolean hasTestSuites() {
return this.testSuites != null && this.testSuites.size() > 0;
}
}
#XmlRootElement(name = "testSuite")
#XmlAccessorType(XmlAccessType.FIELD)
public class TestSuite {
#XmlElement(name = "startTime")
private String startTime;
#XmlElement(name = "status")
private String status;
#XmlElement(name = "testSuiteName")
private String testSuiteName;
#XmlElement(name = "timeTaken")
private String timeTaken;
#XmlElementWrapper(name = "testRunnerResults")
#XmlElement(name = "testCase", type = TestCase.class)
private List<TestCase> testRunnerResults;
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public void setStatus(String status) {
this.status = status;
}
public void setTestSuiteName(String testSuiteName) {
this.testSuiteName = testSuiteName;
}
public void setTimeTaken(String timeTaken) {
this.timeTaken = timeTaken;
}
public void setTestRunnerResults(List<TestCase> testRunnerResults) {
this.testRunnerResults = testRunnerResults;
}
public String getTestSuitename() {
return this.testSuiteName;
}
public List<TestCase> getTestCases() {
return this.testRunnerResults;
}
public boolean hasTestCases() {
return this.testRunnerResults != null;
}
}
#XmlRootElement(name = "testCase")
#XmlAccessorType(XmlAccessType.FIELD)
public class TestCase {
#XmlElement(name = "reason")
private String reason;
#XmlElement(name = "startTime")
private String startTime;
#XmlElement(name = "status")
private String status;
#XmlElement(name = "testCaseId")
private String testCaseId;
#XmlElement(name = "testCaseName")
private String testCaseName;
#XmlElement(name = "timeTaken")
private String timeTaken;
#XmlElementWrapper(name = "testStepResults")
#XmlElement(name = "result")
private List<TestStepResult> testStepResults;
#XmlElementWrapper(name = "testStepParameters")
#XmlElement(name = "parameters")
private List<TestStepParameter> testStepParameters;
#XmlElementWrapper(name = "failedTestSteps")
#XmlElement(name = "error")
private List<TestStepError> failedTestSteps;
public void setReason(String reason) {
this.reason = reason;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public void setStatus(String status) {
this.status = status;
}
public void setTestCaseId(String testCaseId) {
this.testCaseId = testCaseId;
}
public void setTestCaseName(String testCaseName) {
this.testCaseName = testCaseName;
}
public void setTimeTaken(String timeTaken) {
this.timeTaken = timeTaken;
}
public void setTestStepResults(List<TestStepResult> testStepResults) {
this.testStepResults = testStepResults;
}
public void setTestStepParameters(List<TestStepParameter> testStepParameters) {
this.testStepParameters = testStepParameters;
}
public void setFailedTestSteps(List<TestStepError> failedTestSteps) {
this.failedTestSteps = failedTestSteps;
}
public String getReason() {
return this.reason;
}
public String getStartTime() {
return this.startTime;
}
public String getStatus() {
return this.status;
}
public String getTestCaseId() {
return this.testCaseId;
}
public String getTestCaseName() {
return this.testCaseName;
}
public String getTimeTaken() {
return this.timeTaken;
}
public List<TestStepResult> getTestStepResults() {
return this.testStepResults;
}
public List<TestStepParameter> getTestStepParameters() {
return this.testStepParameters;
}
public List<TestStepError> getFailedTestSteps() {
return this.failedTestSteps;
}
}
#XmlRootElement(name = "result")
#XmlAccessorType(XmlAccessType.FIELD)
public class TestStepResult {
#XmlElement(name = "message")
private String message;
#XmlElement(name = "name")
private String testStepName;
#XmlElement(name = "order")
private int order;
#XmlElement(name = "started")
private String started;
#XmlElement(name = "status")
private String status;
#XmlElement(name = "timeTaken")
private String timeTaken;
public void setMessage(String message) {
this.message = message;
}
public void setTestStepName(String testStepName) {
this.testStepName = testStepName;
}
public void setOrder(int order) {
this.order = order;
}
public void setStarted(String started) {
this.started = started;
}
public void setStatus(String status) {
this.status = status;
}
public void setTimeTaken(String timeTaken) {
this.timeTaken = timeTaken;
}
public String getTestStepName() {
return this.testStepName;
}
}
#XmlRootElement(name = "paramters")
#XmlAccessorType(XmlAccessType.FIELD)
public class TestStepParameter {
#XmlElement(name = "iconPath")
private String iconPath;
#XmlElement(name = "testStepName")
private String testStepName;
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
public void setTestStepName(String testStepName) {
this.testStepName = testStepName;
}
public String getTestStepName() {
return this.testStepName;
}
}
#XmlRootElement(name = "error")
#XmlAccessorType(XmlAccessType.FIELD)
public class TestStepError {
#XmlElement(name = "detail")
private String detail;
#XmlElement(name = "icon")
private String icon;
#XmlElement(name = "testCaseName")
private String testCaseName;
#XmlElement(name = "testStepName")
private String testStepName;
#XmlElement(name = "testSuiteName")
private String testSuiteName;
public void setDetail(String detail) {
this.detail = detail;
}
public void setIcon(String icon) {
this.icon = icon;
}
public void setTestCaseName(String testCaseName) {
this.testCaseName = testCaseName;
}
public void setTestStepName(String testStepName) {
this.testStepName = testStepName;
}
public void setTestSuiteName(String testSuiteName) {
this.testSuiteName = testSuiteName;
}
}
The Example.xml is how the report is generated, I have begun attempting to marshal it myself using sample data to confirm I am building this correctly. I've been able to get this response:
<testSuiteResults>
<testSuite>
<startTime>00:00:00</startTime>
<status>PASS</status>
<testSuiteName>TestSuiteName</testSuiteName>
<timeTaken>123</timeTaken>
<testRunnerResults/>
</testSuite>
</testSuiteResults>
It always stops on populating testRunnerResults, so I've attempted to look into XmlAdapters but I have had a lot of trouble understanding how to work it into this structure.
I am a novice in SAXParser. I don't know is it possible to parse complex object with SAXParser. I have a class which contain Item list. And my response xml is like that :
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GetPaymentServiceInfoResponse xmlns="http://quetzalcoatlus/EpulPaymentService"><GetPaymentServiceInfoResult><ResultCodes>OK</ResultCodes><Description>User is temporary blocked</Description><Items><Item><Amount>122</Amount></Item><Item><Amount>23232</Amount></Item></Items></GetPaymentServiceInfoResult></GetPaymentServiceInfoResponse></s:Body></s:Envelope>
And my POJO class is like following:
#XmlRootElement(name = "PGResponse")
public class CheckAbonSuccessResponseModel {
private String message;
private String message_code;
private BigDecimal amount;
private String invoiceCode;
private String operationCode;
private List<Item> items;
#XmlElement(name = "message")
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
#XmlElement(name = "message_code")
public String getMessage_code() {
return message_code;
}
public void setMessage_code(String message_code) {
this.message_code = message_code;
}
#XmlElement(name = "amount")
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
#XmlElement(name = "invoice_code")
public String getInvoiceCode() {
return invoiceCode;
}
public void setInvoiceCode(String invoiceCode) {
this.invoiceCode = invoiceCode;
}
#XmlElement(name = "operation_code")
public String getOperationCode() {
return operationCode;
}
public void setOperationCode(String operationCode) {
this.operationCode = operationCode;
}
#XmlElement(name = "items")
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
#XmlRootElement(name = "item")
public static class Item {
private String label;
private String value;
#XmlElement(name = "label")
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
#XmlElement(name = "value")
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
How I can parse my xml string to CheckAbonSuccessResponseModel. Is it possible or not? I was trying but it shows just amount inside Result element.I need just know how I must write DefaultHandler class.
Thanks in advance.
I'm trying to use JAXB to unmarshal a data (Polygon) with two #XmlJavaTypeAdapter annotations (Subscriber, Tag) to and from an XML file. Each object has it's own XML file, and the objects are related thus:
Each Subscriber may hold multiple Polygons
Each Polygon may hold multiple Subscribers
Each Polygon may hold multiple Tags
I'm trying to unmarshall the Polygon XML file back to its class object, with its Subscribers and Tags in tact, but can't work out how to do it.
== Subscriber.java ==
#XmlRootElement(name = "Subscriber")
#XmlAccessorType(XmlAccessType.FIELD)
public class Subscriber {
private String ID;
private Set<Polygon> polygons;
#XmlAttribute(name = "ID")
public String getID() {
return this.ID;
}
public void setID(String ID) {
this.ID = ID;
}
#XmlJavaAdapter(PolygonXmlAdapter.class)
#XmlElementWrapper(name = "Polygons")
#XmlElement(name = "Polygon")
public set<Polygon> getPolygons() {
return this.polygons;
}
public void setPolygons(Set<Polygon> polygons) {
this.polygons = polygons;
}
}
== Polygon.java ==
#XmlRootElement(name = "{Polygon}")
#XmlAccessorType(XmlAccessType.FIELD)
public class Polygon {
private String ID;
private Set<Subscriber> subscribers;
private Set<Tag> tags
#XmlAttribute(name = "ID")
public String getID() {
return this.ID;
}
public void setID(String ID) {
this.ID = ID;
}
#XmlJavaAdapter(SubscriberXmlAdapter.class)
#XmlElementWrapper(name = "Subscribers")
#XmlElement(Subscriber)
public Set<Subscriber> getSubscribers() {
return this.subscribers;
}
#XmlJavaAdapter(TagXmlAdapter.class)
#XmlElementWrapper(name = "Tags")
#XmlElement(name = "Tag")
public Set<Tag> getTags() {
return this.tags
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
}
== Tag.java ==
#XmlRootElement(name = "Tag")
#XmlAccessorType(XmlAccessType.FIELD)
public class Tag {
private String ID;
#XmlAttribute(name = "ID")
public String getID() {
return this.ID;
}
public void setID(String ID) {
this.ID = ID;
}
}
== SubscriberXmlAdapter.java ==
public class SubscriberXmlAdapter extends XmlAdapter<String, Subscriber> {
private Map<String, Subscriber> subscribers = new HashMap<>();
private Map<String, Subscriber> getSubscribers() {
return subscribers;
}
#Override
public Subscriber unmarshal(String v) throws Exception {
return subscribers.get(v);
}
#Override
public String marshal(Subscriber v) throws Exception {
return v.getID();
}
}
== TagXmlAdapter.java ==
public class TagXmlAdapter extends XmlAdapter<String, Tag> {
private Map<String, Tag> tags = new HashMap<>();
private Map<String, Tag> getTags() {
return tags;
}
#Override
public String unmarshal(String v) throws Exception {
return tags.get(v);
}
#Override
public String marshal(Tag v) throws Exception {
reutrn v.getID();
}
}
== SubscriberCollection.java ==
#XmlRootElement(name = "Subscribers")
#XmlAccessorType(XmlAccessType.FIELD)
public class SubscriberCollection {
private Collection<Subscriber> collection;
#XmlElement(name = "Subscriber")
public Collection<Subscriber> getSubscribers() {
return this.collection;
}
public void setCollection(Collection<Subscriber> collection) {
this.collection = collection;
}
}
== TagCollection.java ==
#XmlRootElement(name = "Tags")
#XmlAccessorType(XmlAccessType.FIELD)
public class TagCollection {
private Collection<Subscriber> collection;
#XmlElement(name="Tag")
public Collection<Tag> getSubscribers() {
return this.collection;
}
public void setCollection(Collection<Subscriber> collection) {
this.collection = collection;
}
}
And to execute the unmarshalling, three xml files - for subscribers, polygons, and tags - containing their respective data are used:
JAXBContext jaxbContext = JAXBContext.newInstance(SubscriberCollection.class, PolygonTagCollection.class, Polygon.class);
unmarshaller subUnmarshaller = jaxbContext.createunmarshaller();
SubscriberCollection subCollection = (SubscriberCollection) subUnmarshaller.unmarshal(new ByteArrayInputStream(subscribersXml.getBytes(StandardCharset.UTF_8.name())));
Unmarshaller tagUnmarshaller = jaxbContext.createUnmarshaller();
TagCollection tagCollectino = (TagCollection) tagUnmarshaller.un,arshal(new ByteArrayInputStream(tagXml.getBytes(StandardCharsets.UTF_8.name())));
Unmarshaller polUnmarshaller = jaxbContext.createUnmarshaller();
SubscriberXmlAdapter subAdapter = new SubscriberXmlAdapter();
for (Subscriber sub : subscriberCollection.getCollection()) {
subAdapter.getCollection().put(sub.getID(), sub);
}
TagXmlAdapter tagAdapter = new TagXmlAdapter();
for (Tag tag : tagCollection.getCollection()) {
tagAdapter.getCollection().put(tag.getID(), tag);
}
polUnmarshaller.setAdapter(SubscriberXmlAdapter.class subAdapter);
polUnmarshaller.unmarshal(new ByteArrayInputStream(polygonXml.getBytes(StandardCharsets.UTF_8.name())));
This unmarshalls the Polygon with the correct subscribers, but not with the correct tags.
I can only set one XmlAdapter to the unmarshaller, so it can only populate the subscribers or the tags within the polygon being unmarshalled.
Is there a way to combine these adapters? Or is there a better way of doing things altogether.
Thanks!
I'm working at a Method to filter a collection (FileList) of xml-files if a specific xml-tag has an attribute...
In detail... I want to filter all xml-files where the xml-tag has an attribute "is_special", but I've problems to setup my model-classes for the attribute.
At the end I want to store the name of the file and a list of its items, where the value has the attribute is_special="true"
Also I'm using the JAXB Framework with the Moxy extension...
The XML-Structure as followed:
<document>
<id>75C8866AB078DCE541256D16002CF636</id>
<size>806220</size>
<author>xxx</author>
<last_modified>2017.06.12 07:15:41 GMT</last_modified>
<added_to_file>2016.07.05 09:50:44 GMT</added_to_file>
<created>2003.04.28 08:11:06 GMT</created>
<items>
<item>
<name>someName/name>
<type>LNITEMTYPE_DATETIMES</type>
<values>
<value is_special="true"/>
</values>
<last_modified>2003.04.28 08:11:10 GMT</last_modified>
...
</item>
<item>
<name>someName/name>
<type>LNITEMTYPE_TEXT</type>
<values>
<value>SOMETEXT</value>
<value>SOMETEXT</value>
</values>
<last_modified>2003.04.28 08:11:10 GMT</last_modified>
...
</item>
</items>
Therefor I've got 3 Classes for the XML-File...
"XMLDocument.java" implements the list of "Items.java" which implements the list of "Value.java"
XMLDocument.java
#XmlRootElement(name = "notes_document")
public class XMLDocument {
...
private List<Item> items;
...
#XmlElementWrapper(name = "items")
#XmlElement(name = "item")
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
item.java
#XmlRootElement(name = "items")
public class Item {
private String name;
private List<String> values;
private boolean valueIsSpecial;
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElementWrapper(name = "values")
#XmlElement(name = "value")
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
#XmlPath("value/#is_special")
public boolean getValueIsSpecial() {
return valueIsSpecial;
}
public void setValueIsSpecial(boolean valueIsSpecial) {
this.valueIsSpecial = valueIsSpecial;
}
}
value.java
#XmlRootElement(name = "values")
public class Value {
#XmlElement(name = "value")
private String itemValue;
#XmlPath("value/#is_special")
private boolean isSpecial;
public String getValue() {
return itemValue;
}
public void setValue(String value) {
this.itemValue = value;
}
public boolean getValueIsSpecial() {
return isSpecial;
}
public void setValueIsSpecial(boolean isSpecial) {
this.isSpecial = isSpecial;
}
}
My Method so far...
public void FilterTree_isSpecial() throws JAXBException, FileNotFoundException {
for(String file: FileList) {
if (file.endsWith(".xml") && !file.contains("databaseinfo.xml")) {
JAXBContext context = JAXBContext.newInstance(NotesDocumentMetaFile.class);
Unmarshaller um = context.createUnmarshaller();
NotesDocumentMetaFile docMetaFile = (XMLDocument) um.unmarshal(new FileReader(file));
for (int i = 0; i < docMetaFile.getItems().size(); i++) {
// CHECK IF THE <value> OF THIS ITEM HAS ATTRIBUTE is_special
}
}
}
}
Much text... I hope anyone can give me a solution :/
Actually the xpath in your Item.java needs to be : values/value/#is_special like #XmlPath("values/value/#is_special")
If you want the is_special in your Value.java also your xpath should be :
#is_special like : #XmlPath(#is_special)
Also your Item.java, Value.java needs a little change. You don't need #XmlRootElement, you already had it in your XmlDocument.java
Your Item.java should be :
public class Item
{
private String name;
private String type;
private String lastModified;
private List<Value> values;
private String isSpecial;
#XmlPath("values/value/#is_special")
public String getIsSpecial() {
return isSpecial;
}
public void setIsSpecial(String isSpecial) {
this.isSpecial = isSpecial;
}
#XmlElement(name="type")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#XmlElement(name="last_modified")
public String getLastModified() {
return lastModified;
}
public void setLastModified(String lastModified) {
this.lastModified = lastModified;
}
#XmlElement(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElementWrapper(name="values")
#XmlElement(name="value")
public List<Value> getValues() {
return values;
}
public void setValues(List<Value> values) {
this.values = values;
}
}
Your Value.java should be :
public class Value
{
#XmlPath("text()")
private String value;
#XmlPath("#is_special")
private String isSpecial;
public String getIsSpecial() {
return isSpecial;
}
public void setIsSpecial(String isSpecial) {
this.isSpecial = isSpecial;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Note that to get value and is_special in Value.java, you could use #XmlPath.
Now you can call getIsSpecial() on Item.java to check if it is special.