How to convert CSV to XML in Java using JAXB

一世执手 提交于 2021-02-11 15:11:26

问题


I am trying to consume a CSV file using apache camel and convert each row to XML and publish each xml to solace topic. XML format is complex and I am not sure how to create such a complex XML in Java. CSV contains employee payload fields. Other part of XML including header, auditRecords and ancillaryData are hardcoded/static data(timestamp can be current date).

How to convert CSV to XML in Java using JAXB?

<canonMessage xmlns="http://www.test.com/canon/v1">
   <header>
      <metadata>
         <domain>
            <name>party</name>
            <schemaVersion>1.0</schemaVersion>
            <subdomain>
               <name>employee</name>
            </subdomain>
         </domain>
         <identifier>
            <id idScheme="HR/lanId">kabcde</id>
         </identifier>
         <source>HR</source>
         <messageId>352247</messageId>
         <version>v1234520171106</version>
      </metadata>
   </header>
   <payload>
      <employee xmlns="http://www.testcompany.com/party/employee/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.testcompany.com/party/employee/v1 employee-v1.xsd">
         <employeeId>a</employeeId>
         <lanId>a</lanId>
         <name>
            <lastName>a</lastName>
            <firstName>a</firstName>
         </name>
         <businessTitle>String</businessTitle>
         <status>String</status>
         <legalEntity>String</legalEntity>
         <groupName>String</groupName>
         <divisionName>String</divisionName>
         <departmentName>String</departmentName>
         <costCentre>String</costCentre>
         <officeLocation>String</officeLocation>
         <region>String</region>
         <citizenship>
            <citizenshipCountry>String</citizenshipCountry>
            <citizenshipCountry>String</citizenshipCountry>
         </citizenship>
      </employee>
   </payload>
   <auditRecords>
      <sourceAuditRecord>
         <system>PeopleSoftHR</system>
         <user />
         <timestamp>
            <created>2016-09-29T09:41:54.436+08:00</created>
            <updated>2016-09-29T09:41:54.436+08:00</updated>
            <sent>2016-09-29T09:42:48.366+08:00</sent>
         </timestamp>
      </sourceAuditRecord>
      <auditRecord>
         <system>listener-settlement</system>
         <timestamp>
            <received>2016-09-29T11:44:56.306+10:00</received>
         </timestamp>
      </auditRecord>
   </auditRecords>
   <ancillaryData>
      <dataClassification xmlns="http://www.test.com/data-classification/v1">
         <compartments>
            <compartment name="domain">employee</compartment>
            <compartment name="confidentiality">confidential</compartment>
         </compartments>
      </dataClassification>
   </ancillaryData>
   <trailer>
      <checksum type="sha-256">df29183132b0733e5afbe5a9ab44f74ee7b43fff4d48daa</checksum>
   </trailer>
</canonMessage>

Employee Class:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@CsvRecord(separator = ",")
public class Employee {

    @DataField(pos = 1)
    @XmlElement
    public String employeeId;
    
    @DataField(pos = 2)
    @XmlElement
    public String lanId;
    
    @DataField(pos = 3)
    @XmlElement
    public String status;
    
    @DataField(pos = 4)
    @XmlElement
    public String costCentre;

    @DataField(pos = 5)
    @XmlElement
    public String groupName;
    
    @DataField(pos = 6)
    @XmlElement
    public String divisionName;
    
    @DataField(pos = 7)
    @XmlElement
    public String departmentName;

    @DataField(pos = 8)
    @XmlElement
    public String region;

    @DataField(pos = 9)
    @XmlElement
    public String businessTitle;

    @DataField(pos = 10)
    @XmlElement
    public String officeLocation;
    
    @DataField(pos = 11)
    @XmlElement
    public String legalEntity;

    @DataField(pos = 12)
    @XmlElement
    public String birthDate;
    
    @DataField(pos = 13)
    @XmlElement
    public String firstName;
    
    @DataField(pos = 14)
    @XmlElement
    public String lastName;

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public String getLanId() {
        return lanId;
    }

    public void setLanId(String lanId) {
        this.lanId = lanId;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getCostCentre() {
        return costCentre;
    }

    public void setCostCentre(String costCentre) {
        this.costCentre = costCentre;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public String getDivisionName() {
        return divisionName;
    }

    public void setDivisionName(String divisionName) {
        this.divisionName = divisionName;
    }

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    public String getBusinessTitle() {
        return businessTitle;
    }

    public void setBusinessTitle(String businessTitle) {
        this.businessTitle = businessTitle;
    }

    public String getOfficeLocation() {
        return officeLocation;
    }

    public void setOfficeLocation(String officeLocation) {
        this.officeLocation = officeLocation;
    }

    public String getLegalEntity() {
        return legalEntity;
    }

    public void setLegalEntity(String legalEntity) {
        this.legalEntity = legalEntity;
    }

    public String getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(String birthDate) {
        this.birthDate = birthDate;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
            
}

Header Class:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="metadata")
@XmlAccessorType(XmlAccessType.FIELD)
public class Header {

    @XmlElementWrapper(name = "domain")
    private List<Domain> domain;
    
    private String id;
    
    private String source;
    
    private String messageId;
    
    private String version;

    public List<Domain> getDomain() {
        return domain;
    }

    public void setDomain(List<Domain> domain) {
        this.domain = domain;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getMessageId() {
        return messageId;
    }

    public void setMessageId(String messageId) {
        this.messageId = messageId;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }
    
    public Header() {
        
    }
    
    public Header(List<Domain> domain, String id, String source, String messageId, String version) {
        this.domain = domain;
        this.id = id;
        this.source = source;
        this.messageId = messageId;
        this.version = version;
    }
}

Domain Class:

@XmlRootElement(name="domain")
@XmlAccessorType(XmlAccessType.FIELD)
public class Domain {

    private String name;
    
    private String schemaVersion;
    
    //@XmlElementWrapper(name = "subdomain")
    private String subdomain;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSchemaVersion() {
        return schemaVersion;
    }
    public void setSchemaVersion(String schemaVersion) {
        this.schemaVersion = schemaVersion;
    }
    public String getSubdomain() {
        return subdomain;
    }
    public void setSubdomain(String subdomain) {
        this.subdomain = subdomain;
    }
    
    public Domain() {
        
    }
    
    public Domain(String name, String schemaVersion, String subdomain) {
        this.name = name;
        this.schemaVersion = schemaVersion;
        this.subdomain = subdomain;
    }
}

Service:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.springframework.stereotype.Service;


@Service
public class HrCanonicalService {

    private final String BOOKSTORE_XML = "app/hrci-files/bookstore-jaxb.xml";
    public void process(Employee employee) {
        
        JAXBContext context;
        try {
            context = JAXBContext.newInstance(CanonMessage.class);
            Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            // Write to System.out
            m.marshal(employee, System.out);

            // Write to File
            m.marshal(employee, new File(BOOKSTORE_XML));
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        
    }
}

回答1:


I managed to create the XML based on the above XML schema. I skipped ancillaryData and auditRecord elements as it was not mandatory. Let me know if this is the correct way of forming the XML.

CanonMessage.java

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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="canonMessage")
@XmlAccessorType(XmlAccessType.FIELD)
public class CanonMessage {

    @XmlElementWrapper(name = "header")
    @XmlElement(name = "metadata")
    private List<Header> metadata;
    
    @XmlElementWrapper(name = "payload")
    @XmlElement(name = "employee")
    private List<Employee> employee;

    @XmlElementWrapper(name = "auditRecords")
    @XmlElement(name = "sourceAuditRecord")
    private List<SourceAuditRecord> sourceAuditRecord;
    
    @XmlElementWrapper(name = "trailer")
    @XmlElement(name = "checksum")
    private List<Trailer> trailer;
    
    public List<Header> getMetadata() {
        return metadata;
    }

    public void setMetadata(List<Header> metadata) {
        this.metadata = metadata;
    }
        
    public List<Employee> getEmployee() {
        return employee;
    }

    public void setEmployee(List<Employee> employee) {
        this.employee = employee;
    }

    public List<SourceAuditRecord> getSourceAuditRecord() {
        return sourceAuditRecord;
    }

    public void setSourceAuditRecord(List<SourceAuditRecord> sourceAuditRecord) {
        this.sourceAuditRecord = sourceAuditRecord;
    }

    public List<Trailer> getTrailer() {
        return trailer;
    }

    public void setTrailer(List<Trailer> trailer) {
        this.trailer = trailer;
    }

}

Header.java

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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="metadata")
@XmlAccessorType(XmlAccessType.FIELD)
public class Header {

    private List<Domain> domain;
    
    @XmlElementWrapper(name = "identifier")
    @XmlElement(name = "id")
    private List<Identifier> identifier;
    
    private String source;
    
    private String messageId;
    
    public List<Domain> getDomain() {
        return domain;
    }

    public void setDomain(List<Domain> domain) {
        this.domain = domain;
    }

    public List<Identifier> getIdentifier() {
        return identifier;
    }

    public void setIdentifier(List<Identifier> identifier) {
        this.identifier = identifier;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getMessageId() {
        return messageId;
    }

    public void setMessageId(String messageId) {
        this.messageId = messageId;
    }
    
    public Header() {
        
    }
    
    public Header(List<Domain> domain, List<Identifier> identifier, String source, String messageId) {
        this.domain = domain;
        this.identifier = identifier;
        this.source = source;
        this.messageId = messageId;
        
    }
}

Identifier.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement(name = "id")
@XmlAccessorType(XmlAccessType.FIELD)
public class Identifier {

    @XmlAttribute(name = "idScheme")
    private String id;

    @XmlValue
    private String Value;
    
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getValue() {
        return Value;
    }

    public void setValue(String value) {
        Value = value;
    }

}

Domain.java

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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="domain")
@XmlAccessorType(XmlAccessType.FIELD)
public class Domain {

    @XmlElement
    private String name;
    
    @XmlElement
    private String schemaVersion;
    
    @XmlElementWrapper(name = "subdomain")
    @XmlElement(name = "name")
    private List<String> subdomain;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSchemaVersion() {
        return schemaVersion;
    }
    public void setSchemaVersion(String schemaVersion) {
        this.schemaVersion = schemaVersion;
    }
    public List<String> getSubdomain() {
        return subdomain;
    }
    public void setSubdomain(List<String> subdomain) {
        this.subdomain = subdomain;
    }
    
    public Domain() {
        
    }
    
    public Domain(String name, String schemaVersion, List<String> subdomain) {
        this.name = name;
        this.schemaVersion = schemaVersion;
        this.subdomain = subdomain;
    }
}

Employee.java

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 org.apache.camel.dataformat.bindy.annotation.CsvRecord;
import org.apache.camel.dataformat.bindy.annotation.DataField;


@XmlRootElement(namespace = Constants.EMPLOYEE_NAMESPACE)
@XmlAccessorType(XmlAccessType.FIELD)
@CsvRecord(separator = ",")
public class Employee {

    @DataField(pos = 1)
    @XmlElement
    private String employeeId;
    
    @DataField(pos = 2)
    @XmlElement
    private String lanId;
    
    @DataField(pos = 3)
    @XmlElement
    private String status;
    
    @DataField(pos = 4)
    @XmlElement
    private String costCentre;

    @DataField(pos = 5)
    @XmlElement
    private String groupName;
    
    @DataField(pos = 6)
    @XmlElement
    private String divisionName;
    
    @DataField(pos = 7)
    @XmlElement
    private String departmentName;

    @DataField(pos = 8)
    @XmlElement
    private String region;

    @DataField(pos = 9)
    @XmlElement
    private String businessTitle;

    @DataField(pos = 10)
    @XmlElement
    private String officeLocation;
    
    @DataField(pos = 11)
    @XmlElement
    private String legalEntity;

    @DataField(pos = 12)
    @XmlElement
    private String birthDate;
    
    @XmlElement
    private Name name;
    
    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public String getLanId() {
        return lanId;
    }

    public void setLanId(String lanId) {
        this.lanId = lanId;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getCostCentre() {
        return costCentre;
    }

    public void setCostCentre(String costCentre) {
        this.costCentre = costCentre;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public String getDivisionName() {
        return divisionName;
    }

    public void setDivisionName(String divisionName) {
        this.divisionName = divisionName;
    }

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    public String getBusinessTitle() {
        return businessTitle;
    }

    public void setBusinessTitle(String businessTitle) {
        this.businessTitle = businessTitle;
    }

    public String getOfficeLocation() {
        return officeLocation;
    }

    public void setOfficeLocation(String officeLocation) {
        this.officeLocation = officeLocation;
    }

    public String getLegalEntity() {
        return legalEntity;
    }

    public void setLegalEntity(String legalEntity) {
        this.legalEntity = legalEntity;
    }

    public String getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(String birthDate) {
        this.birthDate = birthDate;
    }

    public Name getName() {
        return name;
    }

    public void setName(Name name) {
        this.name = name;
    }
}

SourceAuditRecord.java

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;

@XmlRootElement(name="sourceAuditRecord")
@XmlAccessorType(XmlAccessType.FIELD)
public class SourceAuditRecord {

    @XmlElement
    private String system;
    
    @XmlElement
    private List<Timestamp> timestamp;
    
    public String getSystem() {
        return system;
    }

    public void setSystem(String system) {
        this.system = system;
    }

    public List<Timestamp> getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(List<Timestamp> timestamp) {
        this.timestamp = timestamp;
    }
}

Timestamp.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="timestamp")
@XmlAccessorType(XmlAccessType.FIELD)
public class Timestamp {

    @XmlElement
    private String created;
        
    @XmlElement
    private String updated;
        
    @XmlElement
    private String sent;

    public String getCreated() {
        return created;
    }

    public void setCreated(String created) {
        this.created = created;
    }

    public String getUpdated() {
        return updated;
    }

    public void setUpdated(String updated) {
        this.updated = updated;
    }

    public String getSent() {
        return sent;
    }

    public void setSent(String sent) {
        this.sent = sent;
    }   
}

Trailer.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement(name = "checksum")
@XmlAccessorType(XmlAccessType.FIELD)
public class Trailer {

    @XmlAttribute(name = "type")
    private String checksum;

    @XmlValue
    private String Value;
    
    public String getChecksum() {
        return checksum;
    }

    public void setChecksum(String checksum) {
        this.checksum = checksum;
    }
    

    public String getValue() {
        return Value;
    }

    public void setValue(String value) {
        Value = value;
    }
}

Constants.java

public class Constants {

    public static final String SHA_256_HEX = "sha-256";
    public static final String HRCANONICAL_XML = "app/hrci-files/SampleEmployee_V1_20201103.xml";
    public static final String EMPLOYEE_NAMESPACE = "http://www.xxxx/party/employee/v1";
    public static final String HEADER_DOMAIN_NAME = "party";
    public static final String HEADER_SCHEMA_VERSION = "1.0";
    public static final String HEADER_SUB_DOMAIN_NAME = "employee";
    public static final String HEADER_DOMAIN_SOURCE = "HRSystem";
    public static final String HEADER_DOMAIN_MESSAGEID = "HRSystem";
    public static final String HEADER_IDENTIFIER = "HRSystem/lanId";
    
}

Service.java

public void process(Employee employee) {
        logger.info("process employee data started");
        
        CanonMessage message = new CanonMessage();
        
        // Set Header Record start
        String correlationId = java.util.UUID.randomUUID().toString();
        
        logger.info("correlationId - "+correlationId);
        
        List<String> subDomainNameList = new ArrayList<>();
        subDomainNameList.add(Constants.HEADER_SUB_DOMAIN_NAME);
        Domain domain = new Domain(Constants.HEADER_DOMAIN_NAME, Constants.HEADER_SCHEMA_VERSION, subDomainNameList);
        List<Domain> domainList = new ArrayList<>();
        domainList.add(domain);
        Identifier identifier = new Identifier();
        List<Identifier> identifierList = new ArrayList<>();
        identifier.setId(Constants.HEADER_IDENTIFIER);
        identifier.setValue(employee.getLanId());
        identifierList.add(identifier);
        Header header = new Header(domainList, identifierList, Constants.HEADER_DOMAIN_SOURCE, correlationId);
        List<Header> headerList = new ArrayList<>();
        headerList.add(header);
        message.setMetadata(headerList);
        // Set Header Record end
        
        // Set Employee Payload Record start
        List<Employee> employeeList = new ArrayList<>();
        employeeList.add(employee);
        message.setEmployee(employeeList);
        // Set Employee Payload Record start
        
        // Set Audit Record start
        SourceAuditRecord sourceAuditRecord = new SourceAuditRecord();
        sourceAuditRecord.setSystem(Constants.HEADER_DOMAIN_SOURCE);
        
        Timestamp timestamp = new Timestamp();
        DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime myDateObj = LocalDateTime.now();
        String currentDateString = myDateObj.format(myFormatObj);
        logger.info("currentDateString - "+currentDateString);
        timestamp.setCreated(currentDateString);
        timestamp.setSent(currentDateString);
        List<Timestamp> timestampList = new ArrayList<>();
        timestampList.add(timestamp);
        
        sourceAuditRecord.setTimestamp(timestampList);
        
        List<SourceAuditRecord> sourceAuditRecordList = new ArrayList<>();
        sourceAuditRecordList.add(sourceAuditRecord);
        
        message.setSourceAuditRecord(sourceAuditRecordList);
        // Set Audit Record end
        
        // Set Trailer Record start
        String sha256hex = DigestUtils.sha256Hex(Constants.SHA_256_HEX);
        logger.info("sha256hex - "+sha256hex);
        
        List<Trailer> trailerList = new ArrayList<>();
        Trailer trailer = new Trailer();
        trailer.setChecksum(Constants.SHA_256_HEX);
        trailer.setValue(sha256hex);
        trailerList.add(trailer);
        
        message.setTrailer(trailerList);
        
        JAXBContext context;
        try {
            context = JAXBContext.newInstance(CanonMessage.class);
            Marshaller jaxbMarshaller = context.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            // Write to System.out
            jaxbMarshaller.marshal(message, System.out);
            
            StringBuffer sb = new StringBuffer();
            StringWriter sw = new StringWriter();
            jaxbMarshaller.marshal(message, sw);
            String xmlString = sw.toString();
            System.out.println("xmlString - "+xmlString);
            
            SolaceTopicPublisher publisher = new SolaceTopicPublisher();
            publisher.publishMessage(xmlString);
            
            logger.info("Employee data processed");
        } catch (JAXBException e) {
            logger.error("Error occurred while creating XML data : "+e.getMessage());
            e.printStackTrace();
        }
        
    }


来源:https://stackoverflow.com/questions/64637393/how-to-convert-csv-to-xml-in-java-using-jaxb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!