I have the following function which accept an InputStream object, and should read this stream and parse it's content into list<Transaction>
public void importTransactions(InputStream is) {
}
On TDD, the test function gives me a case like this:
@Test
public void givenValidXmlStream_WhenImport_ThenReturnTheExpectedTransactions() {
InputStream is = asStream("<TransactionList>\n" +
" <Transaction type=\"C\" amount=\"1000\" narration=\"salary\" />\n" +
" <Transaction type=\"D\" amount=\"200\" narration=\"rent\" />\n" +
" <Transaction type=\"D\" amount=\"800\" narration=\"other\" />\n" +
"</TransactionList>");
xmlTransactionProcessor.importTransactions(is);
List<Transaction> transactions = xmlTransactionProcessor.getImportedTransactions();
assertThat(transactions, containsInAnyOrder(
newTransaction("D", new BigDecimal(200), "rent"),
newTransaction("C", new BigDecimal(1000), "salary"),
newTransaction("D", new BigDecimal(800), "other")
));
}
How should I implement this function? and how to read XML data from inputStream object?
As the comment suggested you can use JAXB. I tried to make a minimal example with the code you provided. I think from there you can improve the code yourself. The example is based on this guide.
Transaction class:
@XmlRootElement(name = "Transaction")
@XmlAccessorType(XmlAccessType.FIELD)
public class Transaction {
@XmlAttribute(name = "type")
private String type;
@XmlAttribute(name = "amount")
private BigDecimal amount;
@XmlAttribute(name = "narration")
private String narration;
public Transaction() {
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public String getNarration() {
return narration;
}
public void setNarration(String narration) {
this.narration = narration;
}
TransactionList class:
@XmlRootElement(name = "TransactionList")
@XmlAccessorType(XmlAccessType.FIELD)
public class TransactionList {
@XmlElement(name = "Transaction")
private List<Transaction> transactions;
public List<Transaction> getTransactions() {
return transactions;
}
public void setTransactions(List<Transaction> transactions) {
this.transactions = transactions;
}
}
Main class:
public class XMLTest {
public static List<Transaction> xmlToTransactionList(InputStream inputStream) throws JAXBException, ParserConfigurationException, SAXException {
JAXBContext jaxbContext1 = JAXBContext.newInstance(TransactionList.class);
Unmarshaller jaxbUnmarshaller = jaxbContext1.createUnmarshaller();
TransactionList transactionList = (TransactionList) jaxbUnmarshaller.unmarshal(inputStream);
return transactionList.getTransactions();
}
public static void main(String[] args) {
String input = "<TransactionList>\n" +
" <Transaction type=\"C\" amount=\"1000\" narration=\"salary\" />\n" +
" <Transaction type=\"D\" amount=\"200\" narration=\"rent\" />\n" +
" <Transaction type=\"D\" amount=\"800\" narration=\"other\" />\n" +
"</TransactionList>";
InputStream stream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
try {
List<Transaction> transactions = xmlToTransactionList(stream);
for (Transaction transaction : transactions) {
System.out.println(transaction.getType() + " " + transaction.getAmount() + " " + transaction.getNarration());
}
} catch (JAXBException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
}
Output:
C 1000 salary
D 200 rent
D 800 other