Как минимизировать использование if if if в XMLStreamReader при анализе сложного XML
У меня есть образец данных XML ниже, который я хочу преобразовать в простую форму XML.
Я должен создать несколько XML-данных, основанных на вхождении определенного значения элемента в основные XML-данные.
Логика встроена в XMLStreamReader. При этом я должен использовать несколько if if if и код выглядит просто грязно. Кажется, что если еще, если логика растет, если содержит тег XML, растет.
Есть ли лучший шаблон проектирования для реализации этой логики?
Я должен преобразовать XML в Serializable Object, 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;
}
2 ответа
Я бы предложил вам использовать абстрактный класс 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, вероятно (или вы можете установить плагин, если нет) может генерировать xsd
файлы из xml
, Затем вы можете использовать инструмент XJC для генерации java
файлы.