【问题标题】:How to minimize the use of if else if in XMLStreamReader while parsing complex XML解析复杂 XML 时如何在 XMLStreamReader 中尽量减少 if else if 的使用
【发布时间】:2015-05-28 16:27:35
【问题描述】:

我有下面的示例 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;
    }

【问题讨论】:

  • xml数据是后来添加的。

标签: java xml if-statement logic xmlstreamreader


【解决方案1】:

我建议你使用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文件了。

【讨论】:

  • 感谢您的信息。我能够获得 XML 的 xsd 文件,它使用 XJC 工具创建了很多 java 类。有没有一种好方法可以编写自己的自定义 xsd 来创建更少的 JAXB java 类?如果出现问题,调试将是一场噩梦。
  • 生成的类不是强制性的。您可以而且应该根据您的需要简化它们。关于xsd 文件。如果您需要做的只是解析xml,我建议不要浪费您的时间。但是良好的xsd 将帮助您在xml 中进行更改。现在你的 IDE 会标记你的错误。
【解决方案2】:

尝试使用Jaxb,它将xml 转换为java 对象。更基础的例子here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-21
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多