解析用SAX重复的xml嵌套节点

时间:2013-12-03 17:32:17

标签: java xml sax

我已经找了好几天,似乎无法绕过我的问题。我已经能够解析xml文档,但它有子节点重复,然后再返回到父节点。我的解析器似乎正在正确迭代子节点,但我只能看到重复多次的最后一个子节点的结果。

如果父节点包含5个子节点,则会打印5个节点中最后一个节点的结果5次。

我需要在“portfolio”和“trade”之后正确解析xml标签。最终在标记之前获取xml标记以在“交易”之后与子节点对齐并打印,而不重复“交易”中的最后一个节点

赞赏的例子 谢谢

import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;




public class MyHandler extends DefaultHandler {
//List to hold trade object
private List<Portfolio> tradeList = null;
private Portfolio trd = null;

//getter method for trade list
public List<Portfolio> getEmpList() {
    return tradeList;
}


boolean bdate = false;
boolean bfirm = false;
boolean bacctId = false;
boolean bUserId = false;
boolean bseg = false;
boolean btradedate = false;
boolean btradetime = false;
boolean bec = false;
boolean bexch = false;
boolean bpfcode = false;
boolean bpftype = false;
boolean bpe = false;
boolean btradeqty = false;
boolean btradeprice = false;
boolean bmore = false;

@Override
public void startElement(String uri, String localName, String qName, Attributes     attributes)
        throws SAXException {

    if (qName.equalsIgnoreCase("portfolio")) {
        trd = new Portfolio();
        //initialize list
        if (tradeList == null)
            tradeList = new ArrayList<>();  
    } else if (qName.equalsIgnoreCase("firm")) {
        bfirm = true;
    } else if (qName.equalsIgnoreCase("acctId")) {
        bacctId = true;
    } else if (qName.equalsIgnoreCase("UserId")) {
        bUserId = true;
    } else if (qName.equalsIgnoreCase("seg")) {
        bseg = true;
    } else if (qName.equalsIgnoreCase("trade")) {

    } else if (qName.equalsIgnoreCase("tradedate")) {
        btradedate = true;
    } else if (qName.equalsIgnoreCase("tradetime")) {
        btradetime = true;
    } else if (qName.equalsIgnoreCase("ec")) {
        bec = true;
    } else if (qName.equalsIgnoreCase("exch")) {
        bexch = true;
    } else if (qName.equalsIgnoreCase("pfcode")) {
        bpfcode = true;
    } else if (qName.equalsIgnoreCase("pftype")) {
        bpftype = true;
    } else if (qName.equalsIgnoreCase("pe")) {
        bpe = true;
    } else if (qName.equalsIgnoreCase("tradeqty")) {
        btradeqty = true;
    } else if (qName.equalsIgnoreCase("tradeprice")) {
        btradeprice = true;
    } 

}


@Override
public void endElement(String uri, String localName, String qName) throws SAXException      {
    if(qName.equalsIgnoreCase("trade")) {
        tradeList.add(trd); 
    } 



}
@Override
public void characters(char ch[], int start, int length) throws SAXException {

    if (bfirm) {
        //age element, set Employee age
        trd.setFirm(new String(ch, start, length));
        bfirm = false;
    } else if (bacctId) {
        trd.setAcctId(new String(ch, start, length));
        bacctId = false;
    } else if (bUserId) {
        trd.setUserId(new String(ch, start, length));
        bUserId = false;
    } else if (bseg) {
        trd.setSeg(new String(ch, start, length));
        bseg = false;
    } else if (btradedate) {
        trd.setTradedate(new String(ch, start, length));
        btradedate = false;
    } else if (btradetime) {
        trd.setTradetime(new String(ch, start, length));
        btradetime = false;
    } else if (bec) {
        trd.setEC(new String(ch, start, length));
        bec = false;
    } else if (bexch) {
        trd.setExch(new String(ch, start, length));
        bexch = false;
    } else if (bpfcode) {
        trd.setPFCode(new String(ch, start, length));
        bpfcode = false;
    } else if (bpftype) {
        trd.setPFType(new String(ch, start, length));
        bpftype = false;
    } else if (bpe) {
        trd.setPE(new String(ch, start, length));
        bpe = false;
    } else if (btradeqty) {
        trd.setTradeQty(new String(ch, start, length));
        btradeqty = false;
    } else if (btradeprice) {
        trd.setTradePrice(new String(ch, start, length));
        btradeprice = false;
       // bmore = false;
    }


}
} 

以下是我的xml文件的示例

<?xml version="1.0"?>
<XMLFiletoparse>
<created>201311290419</created>
<pointInTime>
    <date>20131129</date>
    <portfolio>
        <firm>999</firm>
        <acctId>1234G5689</acctId>
        <UserId>11AA</UserId>
        <seg>ABC</seg>
        <trade>
            <tradeDate>20131129</tradeDate>
            <tradeTime>08:30:00</tradeTime>
            <ec>ABC</ec>
            <exch>ABC</exch>
            <pfCode>AB</pfCode>
            <pfType>XYZ</pfType>
            <pe>201403</pe>
            <tradeQty>0</tradeQty>
            <tradePrice>1.11111</tradePrice>
        </trade>
        <trade>
            <tradeDate>20131129</tradeDate>
            <tradeTime>08:30:00</tradeTime>
            <ec>ABC</ec>
            <exch>ABC</exch>
            <pfCode>AB</pfCode>
            <pfType>XYZ</pfType>
            <pe>201403</pe>
            <tradeQty>10</tradeQty>
            <tradePrice>2.22222</tradePrice>
        </trade>
        </portfolio>
    <portfolio>
        <firm>888</firm>
        <acctId>454588784KI</acctId>
        <UserId>LMNO3</UserId>
        <seg>ABC</seg>
        <trade>
            <tradeDate>20131129</tradeDate>
            <tradeTime>08:31:08</tradeTime>
            <ec>ABC</ec>
            <exch>ABC</exch>
            <pfCode>AB</pfCode>
            <pfType>XYZ</pfType>
            <pe>201403</pe>
            <tradeQty>6</tradeQty>
            <tradePrice>3.58965</tradePrice>
        </trade>
</portfolio>
  </pointInTime>
</XMLFiletoparse>

这是投资组合类

import java.io.Serializable;
public class Portfolio implements Serializable {
private String date = null;
private String firm = null;
private String acctId = null;
private String UserId = null;
private String seg = null;
private String tradedate = null;
private String tradetime = null;
private String ec = null;
private String exch = null;
private String pfcode = null;
private String pftype = null;
private String pe = null;
private String tradeqty = null;
private String tradeprice = null;

public String getDate() {
    return date;
}
public void setDate(String date) {
    this.date = date;
}
public String getFirm() {
    return firm;
}
public void setFirm(String firm) {
    this.firm = firm;
}
public String getAcctId() {
    return acctId;
}
public void setAcctId(String acctId) {
    this.acctId = acctId;
}
public String getUserId() {
    return UserId;
}
public void setUserId(String UserId) {
    this.UserId = UserId;
}
public String getSeg() {
    return seg;
}
public void setSeg(String seg) {
    this.seg = seg;
}
public String getTradedate() {
    return tradedate;
}
public void setTradedate(String tradedate) {
    this.tradedate = tradedate;
}
public String getTradetime() {
    return tradetime;
}
public void setTradetime(String tradetime) {
    this.tradetime = tradetime;
}
public String getEC() {
    return ec;
}
public void setEC(String ec) {
    this.ec = ec;
}
public String getExch() {
    return exch;
}
public void setExch(String exch) {
    this.exch = exch;
}
public String getPFCode() {
    return pfcode;
}
public void setPFCode(String pfcode) {
    this.pfcode = pfcode;
}
public String getPFType() {
    return pftype;
}
public void setPFType(String pftype) {
    this.pftype = pftype;
}
public String getPE() {
    return pe;
}
public void setPE(String pe) {
    this.pe = pe;
}
public String getTradeQty() {
    return tradeqty;
}
public void setTradeQty(String tradeqty) {
    this.tradeqty = tradeqty;
}
public String getTradePrice() {
    return tradeprice;
}
public void setTradePrice(String tradeprice) {
    this.tradeprice = tradeprice;
}

@Override
public String toString() {
    return "Date: " + this.date + " Firm: " + this.firm + " Acct ID: " + this.acctId + " User ID: " + this.UserId +
            " Seg: " + this.seg + " tradedate: " + this.tradedate + " tradetime: " + this.tradetime +
            " EC: " +this.ec+ " Exch: " +this.exch+ " PFCode: " +this.pfcode+ " PFType: " +this.pftype+
            " PE: " + this.pe + " Trade Qty: " + tradeqty + " Trade Price: " + tradeprice;
}

2 个答案:

答案 0 :(得分:1)

如果trade中存在多个portfolio节点,您只会看到上一个子节点结果,因为您在遇到trd标记后正在初始化portfolio,并且它出现了它只能存储大约1 trade的信息。因此,当有2个或更多trade个标记时,相同的portfolio对象会被修改。现在,由于Java在后台使用引用调用,因此您在列表中添加的对象也会更新为trd,列表中的对象指向相同的内存区域。
您的问题可能有两种解决方案:
1.修改Portfolio类以存储多个trade数据。 (这应该是基于XML结构的实现)
2.在trd = new Portfolio()

中移动行else if (qName.equalsIgnoreCase("trade"))

答案 1 :(得分:0)

我发布了更新的投资组合类。我必须基本上将父节点值保存到变量,并将子节点变量传递给它们,以便插入到数据库中,所有字段都填充了正确的数据。当到达下一个父节点时,父节点的变量仅使用新值更新。这使得数据的完整性保持正确的行到行。     package risk_mgnt_manager;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;



public class Portfolio implements Serializable {
final private static String JDBC_CONNECTION_URL = "com.mysql.jdbc.Driver";
final private static String DB_URL = "jdbc:mysql://123.456.789.123/DB_Name";
final private static String USER = "user";
final private static String PASS = "pass";

private Connection connection;
private String firm = null;
private String acctId = null;
private String UserId = null;
private String seg = null;
private String tradedate = null;
private String tradetime = null;
private String ec = null;
private String exch = null;
private String pfcode = null;
private String pftype = null;
private String pe = null;
private String tradeqty = null;
private String tradeprice = null;

private String ffirm = null;
private String facctId = null;
private String fUserId = null;
private String fseg = null;
private String ftradedate = null;
private String ftradetime = null;
private String fec = null;
private String fexch = null;
private String fpfcode = null;
private String fpftype = null;
private String fpe = null;
private String ftradeqty = null;
private String ftradeprice = null;
private List results;

//parent nodes with if else statements check if there is new value for variable
public String getFirm() {
    return firm;
}
public void setFirm(String firm) {
    this.firm = firm;
    if(firm == null){
        ffirm = ffirm;
    } else {
        ffirm = firm;
    }
}
public String getAcctId() {
    return acctId;
}
public void setAcctId(String acctId) {
    this.acctId = acctId;
    if(acctId == null){
        facctId = facctId;
    } else {
        facctId = acctId;
    }
}
public String getUserId() {
    return UserId;
}
public void setUserId(String UserId) {
    this.UserId = UserId;
    if(UserId == null){
        fUserId = fUserId;
    } else {
        fUserId = UserId;
    }
}
public String getSeg() {
    return seg;
}
public void setSeg(String seg) {
    this.seg = seg;
    if(seg == null){
        fseg = fseg;
    } else {
        fseg = seg;
    }
}
// no if else statement from here on out. this is the child node data and 
// it is always present
public String getTradedate() {
    return tradedate;
}
public void setTradedate(String tradedate) {
    this.tradedate = tradedate;
    ftradedate = tradedate;
}
public String getTradetime() {
    return tradetime;
}
public void setTradetime(String tradetime) {
    this.tradetime = tradetime;
    ftradetime = tradetime;
}
public String getEC() {
    return ec;
}
public void setEC(String ec) {
    this.ec = ec;
    fec = ec;
}
public String getExch() {
    return exch;
}
public void setExch(String exch) {
    this.exch = exch;
    fexch = exch;
}
public String getPFCode() {
    return pfcode;
}
public void setPFCode(String pfcode) {
    this.pfcode = pfcode;
    fpfcode = pfcode;
}
public String getPFType() {
    return pftype;
}
public void setPFType(String pftype) {
    this.pftype = pftype;
    fpftype = pftype;
}
public String getPE() {
    return pe;
}
public void setPE(String pe) {
    this.pe = pe;
    fpe = pe;
}
public String getTradeQty() {
    return tradeqty;
}
public void setTradeQty(String tradeqty) {
    this.tradeqty = tradeqty;
    ftradeqty = tradeqty;
}
public String getTradePrice() {
    return tradeprice;
}
public void setTradePrice(String tradeprice) {
    this.tradeprice = tradeprice;
    ftradeprice = tradeprice;
    // data from parser is sent to list
    toList(ffirm,facctId,fUserId,fseg,ftradedate,tradetime,fec,fexch,
            fpfcode,fpftype,fpe,ftradeqty,ftradeprice);

}

/*
This will ultimately be the setup to import the list into my database
I only printed the results to make sure I am getting the correct output
*/
public void toList(String a,String b,String c,String d,String e,String f,
        String g,String h,String i,String j,String k,String l,String m){

    importData(ffirm,facctId,fUserId,fseg,ftradedate,tradetime,fec,fexch,
            fpfcode,fpftype,fpe,ftradeqty,ftradeprice);
}

//  public void importData(final List<String> results){
public void importData(String firm,String acctid,String userid,String seg,String    trdDate,String trdTime,
        String ec,String exch,String pfcode,String pftype,String pe,String  trdQty,String trdPrice){

        connection = null;
        try {
                Class.forName(JDBC_CONNECTION_URL);
                connection = DriverManager.getConnection(DB_URL,USER,PASS);

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        String query = "INSERT INTO t_datarlt_trades_wrk (Firm, AcctId, UserID"
                + ", seg, tradedate, tradetime, ec, exch, pfcode, pftype, pe"
                + ", tradeqty, tradeprice) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";

        try{
            //STEP 2: Register JDBC driver
            Class.forName("com.mysql.jdbc.Driver");

            //STEP 3: Open a connection
            connection.setAutoCommit(false);
            PreparedStatement stmt = connection.prepareStatement(query); 

              // for(String result : results){
               stmt.setString(1, firm);
               stmt.setString(2, acctid);
               stmt.setString(3, userid);
               stmt.setString(4, seg);
               stmt.setString(5, trdDate);
               stmt.setString(6, trdTime);
               stmt.setString(7, ec);
               stmt.setString(8, exch);
               stmt.setString(9, pfcode);
               stmt.setString(10, pftype);
               stmt.setString(11, pe);
               stmt.setString(12, trdQty);
               stmt.setString(13, trdPrice);
               stmt.addBatch();
             //  }


            stmt.executeBatch();
            connection.commit();
            //STEP 6: Clean-up environment
            stmt.close();
            connection.close();
            } catch(SQLException sqle) {
       System.out.println("SQLException : " + sqle); 
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }          
}

}
相关问题