简体   繁体   English

解析复杂XML时如何在XMLStreamReader中最小化if if if的使用

[英]How to minimize the use of if else if in XMLStreamReader while parsing complex XML

I have the sample XML data below which I want to convert to a simple XML form. 我有下面的示例XML数据,我想将其转换为简单的XML形式。

I have to create multiple XML data based in the occurrence of certain element-value in the main XML data. 我必须根据主要XML数据中某些元素值的出现来创建多个XML数据。

The logic is embedded inside a XMLStreamReader. 该逻辑嵌入在XMLStreamReader中。 While doing that I have to use multiple if else if and the code looks just messy. 这样做时,我必须使用多个if if,否则代码看起来很混乱。 It seems like the if else if logic seems to grow if the xml tag contains grows. 如果xml标记包含的逻辑增长,则if if if if逻辑似乎增长。

  1. Is there a better design pattern to implement this logic? 是否有更好的设计模式来实现此逻辑?

  2. I have to convert the XML into Serializable Object, Is DOM better option here? 我必须将XML转换为可序列化的对象,在这里DOM更好吗?

XML: 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: 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 Parsing Logic Implementation: 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;
    }

I would suggest you to use JAXB and XmlAdapter abstract class. 我建议您使用JAXBXmlAdapter抽象类。 All you need is in providing links. 您所需要的只是提供链接。 This will be good readable and flexible approach. 这将是一种很好的可读性和灵活性的方法。 Example: 例:

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

This adapter will convert date from String representation to java.util.Date . 该适配器会将日期从String表示形式转换为java.util.Date and vice versa. 反之亦然。 And JAXB object something like that: JAXB对象是这样的:

@XmlRootElement    
@XmlAccessorType(XmlAccessType.FIELD)
public class MyXMLObjectRepresentation {
     @XmlElement
     @XmlJavaTypeAdapter(DateXmlMigrateAdapter.class)
     private Date date;

     public Date getDate() {
         return date;
     }
}

You can start from this JAXB Hello World . 您可以从此JAXB Hello World开始 Some hints. 一些提示。 Your IDE probably(or you can install plugin if doesn't) can generate xsd files from xml . 您的IDE可能(或者如果没有,则可以安装插件)可以从xml生成xsd文件。 Then you can use XJC tool to generate java files. 然后,您可以使用XJC工具生成java文件。

Try using Jaxb , which will convert the xml to java object. 尝试使用Jaxb ,它将把xml转换为java对象。 More basic example here 这里更基本的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM