我有示例 XML 数据,我想将其转换为简单的 XML 形式。
我必须根据主 XML 数据中某些元素值的出现来创建多个 XML 数据。
该逻辑嵌入在 XMLStreamReader 中。在执行此操作时,我必须使用多个 if else if,并且代码看起来很困惑。如果 xml 标签包含增长,则 if else if 逻辑似乎会增长。
是否有更好的设计模式来实现这个逻辑?
我必须将 XML 转换为可序列化对象,DOM 是更好的选择吗?
XML:
<Bank createdTs="2014-11-26T16:50:13" xmlac = "http://www.trans.com/bank" xmlac:trans="http://www.trans.com/bank/dep/trans" xmlac:vref="http://www.trans.com/bank/security/verify">
<Transaction id="6f42cfee-ddd6-4d70-a6f7-a153d182c2b3" trans:type="deposit" trans:method="check">
<UserRef status="Verify" vref:code="13" />
<Account accountID="10002548" accountCategory="Checking">
<TransactionRecord>
<UserID>keith-kolmos</UserID>
<Amount>4480</Amount>
<LocationID>520</LocationID>
<DateTimeStamp>2015-01-23T10:25:18</DateTimeStamp>
<Comments>Check Verification Required</Comments>
</TransactionRecord>
</Account>
</Transaction>
<Transaction id="6f42cfee-ddd6-4d70-a6f7-a33d162c2b3" trans:type="withdraw" trans:method="cash">
<Account accountID="10002548" accountCategory="Checking">
<UserRef status="Complete" vref:code="10"/>
<TransactionRecord>
<UserID>zoe-danbur</UserID>
<Amount>470</Amount>
<LocationID>234</LocationID>
<DateTimeStamp>2015-03-13T11:27:10</DateTimeStamp>
<Comments/>
</TransactionRecord>
</Account>
</Transaction>
<Transaction id="6f42cfee-ddd6-4d70-a6f7-a0124d182c2b0" trans:type="deposit" trans:method="check">
<Account accountID="10002548" accountCategory="Checking">
<UserRef status="verify" vref:code="1"/>
<TransactionRecord>
<UserID>susan-wood</UserID>
<Amount>585</Amount>
<LocationID>127</LocationID>
<DateTimeStamp>2015-03-25T09:20:32</DateTimeStamp>
<Comments>Check Verified, photo ID presented</Comments>
</TransactionRecord>
</Account>
</Transaction>
XML DAO:
public class BankDAO implements Serializable {
private String accountID;
private String accountCategory;
private String transactionID;
private String transactionType;
private String transactionMethod;
private String transactionStatus;
private String transactionCode;
private String userID;
private String locationID;
private String transactionAmount;
private String dateTimeStamp;
private String comments;
//getters
//setters
//toCustomXMLs
}
XML解析逻辑实现:
public BankDAO parseXML(String xml) throws XMLStreamException, FactoryConfigurationError{
XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(new ByteArrayInputStream(xml.getBytes()));
BankDAO bank = new BankDAO();
String currentElement = "";
while (xmlReader.hasNext()){
int code = xmlReader.next();
switch(code){
case START_ELEMENT:
currentElement = xmlReader.getLocalName();
break;
case CHARACTERS:
if (currentElement.equalsIgnoreCase("Transaction")) {
bank.setTransactionID(xmlReader.getAttributeValue("http://www.trans.com/bank/dep/trans","id"));
bank.setTransactionType(xmlReader.getAttributeValue("http://www.trans.com/bank/dep/trans","type"));
bank.setTransactionMethod(xmlReader.getAttributeValue("http://www.trans.com/bank/dep/trans","method"));
} else if (currentElement.equalsIgnoreCase("UserRef")) {
bank.setTransactionStatus(xmlReader.getAttributeValue(null,"status"));
bank.setTransactionCode(xmlReader.getAttributeValue("http://www.trans.com/bank/security/verify","code"));
}else if (currentElement.equalsIgnoreCase("Account")){
bank.setAccountID(xmlReader.getAttributeValue(null,"accountID"));
bank.setAccountCategory(xmlReader.getAttributeValue(null,"accountCategory"));
}else if (currentElement.equalsIgnoreCase("UserID")){
bank.setAccountID(xmlReader.getAttributeValue(null,"UserID"));
}else if (currentElement.equalsIgnoreCase("Amount")){
bank.setTransactionAmount(xmlReader.getElementText());
}else if (currentElement.equalsIgnoreCase("LocationID")){
bank.setLocationID(xmlReader.getElementText());
}else if (currentElement.equalsIgnoreCase("DateTimeStamp")){
bank.setDateTimeStamp(xmlReader.getElementText());
}else if (currentElement.equalsIgnoreCase("Comments")){
bank.setComments(xmlReader.getElementText());
}
}
}
return bank;
}
最佳答案
我建议您使用JAXB和 XmlAdapter抽象类。您所需要的只是提供链接。这将是一种很好的可读性和灵活的方法。 示例:
public class DateXmlAdapter extends XmlAdapter<String, Date> {
public static final String dateFormat = "yyyy-MM-dd'T'HH:mm:ss";
@Override
public Date unmarshal(String v) throws Exception {
return new SimpleDateFormat(dateFormat).parse(v);
}
@Override
public String marshal(Date v) throws Exception {
return v == null ? "" : new SimpleDateFormat(dateFormat).format(v);
}
}
此适配器会将日期从String
表示形式转换为java.util.Date
。反之亦然。 JAXB 对象类似:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MyXMLObjectRepresentation {
@XmlElement
@XmlJavaTypeAdapter(DateXmlMigrateAdapter.class)
private Date date;
public Date getDate() {
return date;
}
}
你可以从这个JAXB Hello World开始。一些提示。您的 IDE 可能(如果没有,您可以安装插件)可以从 xml
生成 xsd
文件。然后你可以使用XJC tool生成 java
文件。
关于java - 如何在解析复杂 XML 时尽量减少 XMLStreamReader 中 if else if 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30512190/