分析输入流 XML 格式 Java



我有一个包含xml格式的输入流,如下所示:-

InputStream is = asStream("<TransactionList>n" +
"    <Transaction type="C" amount="1000"narration="salary" />n" +
"    <Transaction type="X" amount="400" narration="rent"/>n" +
"    <Transaction type="D" amount="750" narration="other"/>n" +
"</TransactionList>");
xmlTransactionProcessor.importTransactions(is);

我正在尝试分析这一点并将值存储到 Transaction 对象(用户定义的)数组列表中,但我仍然无法这样做。

我尝试了许多解决方案,但仍然没有得到任何好处。

我读过关于读取xml文件的信息,但仍然无法处理这样的输入流。

有人可以帮忙吗?这是我的最后一次尝试,但它仍然在某处失败.

// TODO Auto-generated method stub
BufferedReader inputReader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String inline = "";
try {
while ((inline = inputReader.readLine()) != null) {
sb.append(inline);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SAXBuilder builder = new SAXBuilder();
try {
org.jdom2.Document document = (org.jdom2.Document) builder.build(new ByteArrayInputStream(sb.toString().getBytes()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

您不必使用 SAX 解析器自己解析 XML。 有几个库允许 XML 绑定:将 XML 文档序列化和反序列化为自定义 POJO 类(或这些类的集合)。

JDK中甚至还有一个XML绑定标准。 它被称为JAXB。 您可以使用注释将 XML 元素名称映射到自定义 POJO 的属性。

这是我个人最喜欢的图书馆的一个例子:杰克逊。它主要用于处理JSON格式的文本,但具有支持XML(和JAXB)的扩展。

import java.util.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.dataformat.xml.*;
public class XMLTest
{
public static void main(String[] args)
{
String input = 
"<TransactionList>n" +
"    <Transaction type="C" amount="1000" narration="salary" />n" +
"    <Transaction type="X" amount="400" narration="rent"/>n" +
"    <Transaction type="D" amount="750" narration="other"/>n" +
"</TransactionList>";
try {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setDefaultUseWrapper(false);
// this is how we tell Jackson the target type of the deserialization 
JavaType transactionListType = xmlMapper.getTypeFactory().constructCollectionType(List.class, Transaction.class);
List<Transaction> transactionList = xmlMapper.readValue(input, transactionListType );
System.out.println(transactionList);
} catch (Exception e) {
e.printStackTrace();
}
}
public static class Transaction
{
public String type;
public int amount;
public String narration;
@Override
public String toString() {
return String.format("{ type:%s, amount:%d, narration:%s }", type, amount, narration);   
}
}
}

正如 Sharon Ben Asher 所解释的那样,您可以使用 JAXB 或 Jackson 与 XML 数据格式化程序一起使用注释数据映射。这会更容易。

如果您想使用 SAXParser 修复现有代码,请按以下步骤操作。

您必须按照下面的代码迭代文档对象。

public static void main(String[] args) {
InputStream is = new ByteArrayInputStream(("<TransactionList>n" +
"    <Transaction type="C" amount="1000" narration="salary" />n" +
"    <Transaction type="X" amount="400" narration="rent"/>n" +
"    <Transaction type="D" amount="750" narration="other"/>n" +
"</TransactionList>").getBytes(StandardCharsets.UTF_8));
ArrayList transactions = importTransactions(is);
}

importTransaction方法中使用getRootElement获取根级别事务元素。然后使用getChildren和 for-each 循环循环访问每个Transaction子元素。

public static ArrayList<Transaction> importTransactions(InputStream is){
ArrayList<Transaction> transactions = new ArrayList<>();
BufferedReader inputReader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String inline = "";
try {
while ((inline = inputReader.readLine()) != null) {
sb.append(inline);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SAXBuilder builder = new SAXBuilder();
try {
org.jdom2.Document document = builder.build(new ByteArrayInputStream(sb.toString().getBytes()));
Element transactionsElement = document.getRootElement();
List<Element> transactionList = transactionsElement.getChildren();
for (Element transaction:transactionList) {
Transaction t = new Transaction();
t.setType(transaction.getAttribute("type").getValue());
t.setAmount(transaction.getAttribute("amount").getValue());
transactions.add(t);
}
} catch (Exception e) {
// Log the error....
e.printStackTrace();
}
return transactions;
}