How to parse an XML in Java?

Can you please help me in writing the code to parse the following XML file and assign it to hash in Java:

<Report>
  <Date>Wednesday, July 17, 2013  11:41:27</Date>
  <File>
    <name>someFilemname1.cpp</name>
    <FileReport>
      <Check>
        <name>check1</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers>5</ExistingLineNumbers>
          <NewLineNumbers>10</NewLineNumbers>
        </Location>
        <Message>Something happened</Message>
      </Check>
      <Check>
        <name>check2</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers>30,34,38</ExistingLineNumbers>
          <NewLineNumbers>13,45,60</NewLineNumbers>
        </Location>
        <Message>Something not very bad happened</Message>
      </Check>
      <Check>
        <name>check3</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers></ExistingLineNumbers>
          <NewLineNumbers>45,67,78</NewLineNumbers>
        </Location>
        <Message>Something very bad happened</Message>
      </Check>
    </FileReport>
  </File>
    <File>
    <name>someFilename2.cpp</name>
    <FileReport>
      <Check>
        <name>check4</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers>25</ExistingLineNumbers>
          <NewLineNumbers>210</NewLineNumbers>
        </Location>
        <Message>Something just happened</Message>
      </Check>
      <Check>
        <name>check5</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers>230,234,238</ExistingLineNumbers>
          <NewLineNumbers>213,245,260</NewLineNumbers>
        </Location>
        <Message>Something not very bad just happened</Message>
      </Check>
      <Check>
        <name>check6</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers></ExistingLineNumbers>
          <NewLineNumbers>245,267,278</NewLineNumbers>
        </Location>
        <Message>Something very bad just happened</Message>
      </Check>
    </FileReport>
  </File>
</Report>

Open in new window

TolgarAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mccarlIT Business Systems Analyst / Software DeveloperCommented:
and assign it to hash
You will need to elaborate on this part quite a bit more. The data presented in the XML has quite a complex structure and so it can't just be assigned to a simple Java type, I guess you actually mean HashMap.

What part of the XML are you interested in?

What is the ultimate goal, what do you need to do with this data? This will affect how it should be represented in your program.
0
TolgarAuthor Commented:
You are right. I meant to say hashmap.

I am interested in the bold printed data below. It is actually everything.

What I want to do is to know the status of each check for each  file and the line numbers that causes the issues:

For example for the first file and the first check:

File-> someFilemname1.cpp
  Check -> check1
    CheckStatus -> FAILED
    Location
       ExistingLineNumbers -> 5
       NewLineNumbers -> 10
    Message -> Something happened

Open in new window



And I need to know all of this data for all files and checks.

<Report>
  <Date>Wednesday, July 17, 2013  11:41:27</Date>
  <File>
    <name>someFilemname1.cpp</name>
    <FileReport>
      <Check>
        <name>check1</name>
        <CheckStatus>FAILED</CheckStatus>
        <Location>
          <ExistingLineNumbers>5</ExistingLineNumbers>
          <NewLineNumbers>10</NewLineNumbers>
        </Location>
        <Message>Something happened</Message>
      </Check>
      <Check>
        <name>check2</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers>30,34,38</ExistingLineNumbers>
          <NewLineNumbers>13,45,60</NewLineNumbers>
        </Location>
        <Message>Something not very bad happened</Message>
      </Check>
      <Check>
        <name>check3</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers></ExistingLineNumbers>
          <NewLineNumbers>45,67,78</NewLineNumbers>
        </Location>
        <Message>Something very bad happened</Message>
      </Check>
    </FileReport>
  </File>
    <File>
    <name>someFilename2.cpp</name>
    <FileReport>
      <Check>
        <name>check4</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers>25</ExistingLineNumbers>
          <NewLineNumbers>210</NewLineNumbers>
        </Location>
        <Message>Something just happened</Message>
      </Check>
      <Check>
        <name>check5</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers>230,234,238</ExistingLineNumbers>
          <NewLineNumbers>213,245,260</NewLineNumbers>
        </Location>
        <Message>Something not very bad just happened</Message>
      </Check>
      <Check>
        <name>check6</name>
        <CheckStatus>PASSED</CheckStatus>
        <Location>
          <ExistingLineNumbers></ExistingLineNumbers>
          <NewLineNumbers>245,267,278</NewLineNumbers>
        </Location>
        <Message>Something very bad just happened</Message>
      </Check>
    </FileReport>
  </File>
</Report>

After I get this data, I will put it in a table in a GUI in Java. The table is actually ready for some fake data. Now I need to put some actual data from the this XML file.

It is not related but this is now I created my table:

        //TAB3 CONTENT
        //This is the progress bar
        GridLayout progressBarGridLayout = new GridLayout();
        progressBarGridLayout.numColumns = 1;
        GridData progressBarGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
        RunCheckProgressBar progressBar = new RunCheckProgressBar();
        progressBar.createProgressBar(compTab3, progressBarGridData);
        
        //This is the results table
        Table table = new Table(compTab3, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
        //GridData resultsGridData = new GridData(1, 100, false, false);
        table.setLayout(progressBarGridLayout);
        table.setHeaderVisible(true);
        String[] titles = { "Override", "Rerun", "Check/Error", "Filename", "Line" };
        
        for (int loopIndex = 0; loopIndex < titles.length; loopIndex++) {
            TableColumn column = new TableColumn(table, SWT.NULL);
            column.setText(titles[loopIndex]);
            column.setWidth(80);
        }
        
        for (int loopIndex = 0; loopIndex < 20; loopIndex++) {
            TableItem item = new TableItem(table, SWT.NULL);
            item.setText(0, "yes");
            item.setText(1, "0");
            item.setText(2, "Spellcheck");
            item.setText(3, "/main/lib/filename" + loopIndex + ".cpp");
            item.setText(4, "50" + loopIndex*4);
            if (loopIndex % 2 == 0) item.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
         }
          
         for (int loopIndex = 0; loopIndex < titles.length; loopIndex++) {
              table.getColumn(loopIndex).pack();
         }
          
         GridData data3 = new GridData(GridData.FILL_HORIZONTAL);
         data3.verticalAlignment = SWT.BOTTOM;
         data3.horizontalSpan = 2;
         table.setLayoutData(data3);

Open in new window

0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Ok, so since this is going into a table, I am thinking a List of objects, where each of those objects represents the data in the columns of your table. Therefore, the List of these represents the rows of the table. This custom object has fields that represent each of column values.

So if you have a class to represent one column of data, such as...
public class CheckDetail {
    private String name;
    private String status;
    private String fileName;
    private String existingLineNumbers;
    private String newLineNumbers;
    private String message;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    public String getExistingLineNumbers() {
        return existingLineNumbers;
    }
    public void setExistingLineNumbers(String existingLineNumbers) {
        this.existingLineNumbers = existingLineNumbers;
    }
    public String getNewLineNumbers() {
        return newLineNumbers;
    }
    public void setNewLineNumbers(String newLineNumbers) {
        this.newLineNumbers = newLineNumbers;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    
    @Override
    public String toString() {
        return "CheckDetail [name=" + name + ", status=" + status + ", fileName=" + fileName + ", existingLineNumbers=" + existingLineNumbers + ", newLineNumbers=" + newLineNumbers + ", message=" + message + "]";
    }
}

Open in new window

And then you can use code like this to parse that XML into a List of CheckDetail objects...
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ParseXML {
    
    public static void main(String[] args) {
        new ParseXML().parse();
    }

    public void parse() {
        try {
            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("tolgarInput.xml"));
            
            NodeList fileNodes = doc.getElementsByTagName("File");
            
            List<CheckDetail> checkDetails = new ArrayList<CheckDetail>();
            
            for (int i = 0; i < fileNodes.getLength(); i++) {
                String fileName = null;
                Element fileReportElement = null;
                NodeList fileChildren = fileNodes.item(i).getChildNodes();
                for (int j = 0; j < fileChildren.getLength(); j++) {
                    if ("name".equals(fileChildren.item(j).getNodeName())) {
                        fileName = fileChildren.item(j).getTextContent();
                    }
                    if ("FileReport".equals(fileChildren.item(j).getNodeName())) {
                        fileReportElement = (Element) fileChildren.item(j);
                    }
                }
                
                if (fileName != null && fileReportElement != null) {
                    NodeList checkNodes = fileReportElement.getChildNodes();
                    for (int j = 0; j < checkNodes.getLength(); j++) {
                        if ("Check".equals(checkNodes.item(j).getNodeName())) {
                            CheckDetail checkDetail = new CheckDetail();
                            checkDetail.setFileName(fileName);
                            
                            setDetailFromNodeList(checkDetail, checkNodes.item(j).getChildNodes());
                            
                            checkDetails.add(checkDetail);
                        }
                    }
                }
            }
            
            
            
            // Do something with the List of CheckDetails
            System.out.println(checkDetails);
            
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void setDetailFromNodeList(CheckDetail checkDetail, NodeList nodeList) {
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if ("name".equals(node.getNodeName())) {
                checkDetail.setName(node.getTextContent());
            }
            if ("CheckStatus".equals(node.getNodeName())) {
                checkDetail.setStatus(node.getTextContent());
            }
            if ("Location".equals(node.getNodeName())) {
                setDetailFromNodeList(checkDetail, node.getChildNodes());
            }
            if ("ExistingLineNumbers".equals(node.getNodeName())) {
                checkDetail.setExistingLineNumbers(node.getTextContent());
            }
            if ("NewLineNumbers".equals(node.getNodeName())) {
                checkDetail.setNewLineNumbers(node.getTextContent());
            }
            if ("Message".equals(node.getNodeName())) {
                checkDetail.setMessage(node.getTextContent());
            }
        }
    }
    
}

Open in new window

The above just prints out the contents of the List but in your code you can iterate through that List and then add the appropriate TableItem objects with their values set with the data retrieved via the various getXXX methods of CheckDetail.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TolgarAuthor Commented:
Perfect answer!
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Your welcome! :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.