java - 如何在解析复杂 XML 时尽量减少 XMLStreamReader 中 if else if 的使用

标签 java xml if-statement logic xmlstreamreader

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

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

该逻辑嵌入在 XMLStreamReader 中。在执行此操作时,我必须使用多个 if else if,并且代码看起来很困惑。如果 xml 标签包含增长,则 if else 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 tool生成 java 文件。

关于java - 如何在解析复杂 XML 时尽量减少 XMLStreamReader 中 if else if 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30512190/

相关文章:

C 宏 : #if check for equality

python - 不满足条件时将 "?"添加到字符串

java - 使用 session 作用域 Bean

java - 我如何用 Java 编写一个测试用例来测试输入是否为 int?

c# - 跨语言(java和c#)对象序列化的策略

ruby-on-rails - ruby REXML : Get Value Of An XML Element

xml - 统计数据和元数据交换 (SDMX)

java - 我该如何改进我的视频上传,目前由于内存不足导致应用程序崩溃

java - spring + hibernate配置错误?类路径资源 [spring.xml] 中的 XML 文档无效

mysql - 如果行存在则显示 'Present',否则显示 'Missing'