2

I want to return new .xml file with validated list base on source xml file. How to rewrite names of details in correct way, for account list using Jackson xmlMapper?

I want to read values from .xml file (Accounts details) and convert it into java objects. I need to group those single accountsnt into list. Than, I validate those accounts using some validators, and than I need to return checked account list to new xml file.

Name "LinkedList" shows, cause I use it in service class to rewrite list.

I give you my code below.

Can someone could help me?

Thanks!

Source XML file:

<accounts>
<account iban="PL61109010140000071219812875">
    <name>name1</name>
    <currency>PLN</currency>
    <balance>123.45</balance>
    <closingDate>2031-06-10</closingDate>
</account>
<account iban="PL61109010140000071219812871">
    <name>name2</name>
    <currency>PLN</currency>
    <balance>85.00</balance>
    <closingDate>2035-10-01</closingDate>
</account>
</accounts>

PARSER:

public class Parser {

private ObjectMapper objectMapper;

public Parser() {
    this.objectMapper = new XmlMapper();
}

public AccountList readFromXML() throws IOException {
    return objectMapper.readValue(
            readTextFromFile(), AccountList.class);
}

public void writeToXML(List<Account> account) throws IOException,     XMLStreamException {
    StringWriter stringWriter = new StringWriter();
    XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
    XMLStreamWriter sw = xmlOutputFactory.createXMLStreamWriter(stringWriter);

    XmlMapper mapper = new XmlMapper();
    objectMapper.writeValue(new
            File("src/main/resources/SortedData.xml"), account);
    sw.writeStartDocument();


}

private String readTextFromFile() throws IOException {

    InputStream in = new FileInputStream("src/main/resources/SourceData.xml");
    BufferedReader buff = new BufferedReader(new InputStreamReader(in));

    String line = buff.readLine();
    StringBuilder builder = new StringBuilder();

    while(line != null){
        builder.append(line).append("\n");
        line = buff.readLine(); }

    return builder.toString();
}
}

Account class:

public final class Account implements Serializable {

private static final long serialVersionUID = -4816735989159211337L;
@JacksonXmlProperty(localName = "iban", isAttribute = true)
private String accountIban;
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlProperty(localName = "currency")
private String currency;
@JacksonXmlProperty(localName = "balance")
private BigDecimal balance;
@JacksonXmlProperty(localName = "closingDate")
private String closingDate;

public Account() {
}

public Account(String accountIban, String name, String currency, BigDecimal balance, String closingDate) {
    this.accountIban = accountIban;
    this.name = name;
    this.currency = currency;
    this.balance = balance;
    this.closingDate = closingDate;
}

(I HAVE BASIC GETTERS AND SETTERS IN THS PLACE, BUT I DIDN'T PASE IT)   

@Override
public String toString() {
    return "Account{" +
            "accountNumber='" + accountIban + '\'' +
            ", name='" + name + '\'' +
            ", currency='" + currency + '\'' +
            ", balance=" + balance +
            ", closingDate=" + closingDate +
            '}';
}

@Override
public int hashCode() {
    return super.hashCode();
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Account account = (Account) o;
    return Objects.equals(accountIban, account.accountIban) &&
            Objects.equals(name, account.name) &&
            Objects.equals(currency, account.currency) &&
            Objects.equals(balance, account.balance) &&
            Objects.equals(closingDate, account.closingDate);
}
}

ACCOUNT LIST:

@JacksonXmlRootElement(localName = "accounts")
@XmlAccessorType(XmlAccessType.FIELD)
public final class AccountList implements Serializable {


private static final long serialVersionUID = 9215731280802778862L;

@JacksonXmlElementWrapper(localName = "accountList", useWrapping = false)
private List<Account> accountList;

public AccountList() {
}

GETTERS AND SETTERS IN THIS PLACE

@Override
public String toString() {
    return "Employees{" +
            "employees=" + accountList.toString() +
            '}';
}
}

SERVICE CLASS:

private AccountValidatorsImpl validators;

public AccountServiceImpl() {
    this.validators = new AccountValidatorsImpl();
}

@Override
public List<Account> validateEverySingleAccount(List<Account> sourceAccountList) {
    List<Account> validatedList = new LinkedList<>();
    for (Account account: sourceAccountList) {
        if(validators.checkAllValidators(account))
            validatedList.add(account);
    }
    return validatedList;
}

@Override
public List<Account> sortValidatedAccountList(List<Account> validatedAccountList){
    List<Account> sortedList = new LinkedList<>(validatedAccountList);

    Comparator<Account> comparator = (o1, o2) -> o1.getName().compareTo(o2.getName());

    sortedList.sort(comparator);
    return sortedList;
}
}

MAIN CLASS:

public static void main(String[] args) throws IOException, XMLStreamException {

    Parser parser = new Parser();
    AccountServiceImpl service = new AccountServiceImpl();
    AccountList list = parser.readFromXML();

    List<Account> listOfAccounts = list.getAccountList();
    List<Account> listOfValidatedAccounts = service.validateEverySingleAccount(listOfAccounts);
    List<Account> listOfSortedAccounts = service.sortValidatedAccountList(listOfValidatedAccounts);
    parser.writeToXML(listOfSortedAccounts);


OBJECT SERVICE IS CLASS WHERE I DO VALIDATION. IF IT WILL BE NESSECERY I   WILL PASTE IT

FINAL GENERATED XML FILE:

<LinkedList>
<item iban="PL61109010140000071219812875">
    <name>name1</name>
    <currency>PLN</currency>
    <balance>123.45</balance>
    <closingDate>2031-06-10</closingDate>
</item>
<item iban="PL61109010140000071219812871">
    <name>name2</name>
    <currency>PLN</currency>
    <balance>85.00</balance>
    <closingDate>2035-10-01</closingDate>
</item>
</LinkedList>

Unfortunately, during processing, program missing names, it is:loosing < accounts > and return < LinkedList > and < account > and give < item >. I need the same names for values.

1 Answer 1

1

You forget to wrap List<Account> with AccountList. I fixed your Parser class which reads and writes XML using Jackson classes only. See below example:

import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

public class XmlMapperApp {

    public static void main(String[] args) throws Exception {
        File inputFile = new File("./resource/test.xml").getAbsoluteFile();
        File outputFile = new File("./resource/output.xml").getAbsoluteFile();

        Parser parser = new Parser();
        List<Account> accounts = parser.readFromXML(inputFile).getAccountList();
        accounts.remove(0);
        parser.writeToXML(accounts, outputFile);
    }
}

class Parser {

    private XmlMapper xmlMapper;

    public Parser() {
        this.xmlMapper = new XmlMapper();
        this.xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
    }

    public AccountList readFromXML(File xmlFile) throws IOException {
        return xmlMapper.readValue(xmlFile, AccountList.class);
    }

    public void writeToXML(List<Account> accounts, File output) throws IOException {
        xmlMapper.writeValue(output, new AccountList(accounts));
    }
}

class Account implements Serializable {

    private static final long serialVersionUID = -4816735989159211337L;

    @JacksonXmlProperty(localName = "iban", isAttribute = true)
    private String accountIban;

    @JacksonXmlProperty(localName = "name")
    private String name;

    @JacksonXmlProperty(localName = "currency")
    private String currency;

    @JacksonXmlProperty(localName = "balance")
    private BigDecimal balance;

    @JacksonXmlProperty(localName = "closingDate")
    private String closingDate;

    public Account() {
    }

    public Account(String accountIban, String name, String currency, BigDecimal balance, String closingDate) {
        this.accountIban = accountIban;
        this.name = name;
        this.currency = currency;
        this.balance = balance;
        this.closingDate = closingDate;
    }

    // getters, setters, toString
}

@JacksonXmlRootElement(localName = "accounts")
class AccountList implements Serializable {

    private static final long serialVersionUID = 9215731280802778862L;

    @JacksonXmlProperty(localName = "account")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Account> accountList;

    public AccountList() {
    }

    public AccountList(List<Account> accountList) {
        this.accountList = accountList;
    }

    // getters, setters, toString
}

Above code deserialises XML payload, removes 0-index item and writes rest of items to output.xml file which looks like this:

<accounts>
  <account iban="PL61109010140000071219812871">
    <name>name2</name>
    <currency>PLN</currency>
    <balance>85.00</balance>
    <closingDate>2035-10-01</closingDate>
  </account>
</accounts>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.