Question

I have looked for days and I can't seem to wrap my head around my issue. I have been able to parse the xml doc but it has child nodes that repeat before moving back up to the parent node. My parser seems to be iterating through the child nodes correctly but I can only see the results of the last child node which is repeated multiple times.

If a parent node contains 5 child nodes, it prints the result of the last of the 5 nodes 5 times.

I need the xml tags after "portfolio" and "trade" to parse correctly. Ultimately get the xml tags before the tag to line up and print with the child nodes after "trade" without repeating the last node inside "trade"

Examples are appreciated Thank you

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


}
} 

Here is an example of my xml file

<?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>

Here is portfolio class

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;
}
Was it helpful?

Solution

You are seeing last child node result only, in case of multiple trade node in portfolio, because you are initializing trd after encountering portfolio tag, and it appears it can only store info about 1 trade. So, when there are 2 or more trade tags, same portfolio object gets modified. Now since Java works with call by reference at the background, the object you added in the list also gets updated as trd and object in list points to same memory area.
There could be two solutions to your problem:
1. Modify Portfolio class to store more than 1 trade data. (This should be the implementation based on your XML structure)
2. Move line trd = new Portfolio() inside else if (qName.equalsIgnoreCase("trade"))

OTHER TIPS

I am posting an updated portfolio class. I had to essentially save the parent node values to a variable and pass them with the children node variables to be inserted into a database with all fields populated with the proper data. The variables for the parent node only update with a new value when the next parent node is reached. This kept the integrity of the data correct row to row. 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();
            }          
}

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top