如何从 inputStream 对象中读取 XML 数据?

How can I read XML data from inputStream object?

我有以下接受 InputStream 对象的函数,应该读取该流并将其内容解析为 list<Transaction>

public void importTransactions(InputStream is) {
   
} 

在 TDD 上,测试函数给了我这样一个案例:

@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")
        ));
    }

我该如何实现这个功能?以及如何从 inputStream 对象读取 XML 数据?

正如评论所建议的那样,您可以使用 JAXB。我试图用你提供的代码做一个最小的例子。我认为您可以从那里自己改进代码。该示例基于 this 指南。

交易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;
    }

事务列表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;
    }
}

主要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();
        }
    }
}

输出:

C 1000 salary
D 200 rent
D 800 other