繁体   English   中英

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

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

我有下面的示例XML数据,我想将其转换为简单的XML形式。

我必须根据主要XML数据中某些元素值的出现来创建多个XML数据。

该逻辑嵌入在XMLStreamReader中。 这样做时,我必须使用多个if if,否则代码看起来很混乱。 如果xml标记包含的逻辑增长,则if if if if逻辑似乎增长。

  1. 是否有更好的设计模式来实现此逻辑?

  2. 我必须将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;
    }

我建议您使用JAXBXmlAdapter抽象类。 您所需要的只是提供链接。 这将是一种很好的可读性和灵活性的方法。 例:

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工具生成java文件。

尝试使用Jaxb ,它将把xml转换为java对象。 这里更基本的例子

暂无
暂无

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

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