This is the first time I'm parsing an XML file. So I will be grateful for any suggestions on how my code may be improved. Or if you could suggest another approach to solving this problem.
One other question that I have is why attributes 'title' and 'score' have switched in the resulting XML file (xml2.xml)?
I've got an original XML file (xml1.xml) which is parsed via a DOM parser.Then I'm using the DOM tree structure to look through player's child nodes and their attributes, checking if the average score is correct, updating incorrect average scores. Then writing a result to a new XML file (xml2.xml).
The original xml1.xml
<?xml version="1.0" encoding="UTF-8"?>
<game>
<player nickname="Rooney">
<challenge title="Mission 1" score="10"></challenge>
<challenge title="Mission 2" score="5"></challenge>
<challenge title="Mission 3" score="7"></challenge>
<average average="256"/>
</player>
<player nickname="Doc">
<challenge title="Mission 1" score="5"></challenge>
<challenge title="Mission 2" score="2"></challenge>
<challenge title="Mission 3" score="8"></challenge>
<average average="5"/>
</player>
<player nickname="Junior">
<challenge title="Mission 1" score="10"></challenge>
<challenge title="Mission 2" score="3"></challenge>
<challenge title="Mission 3" score="5"></challenge>
<average average="6"/>
</player>
<player nickname="Candice">
<challenge title="Mission 1" score="1"></challenge>
<challenge title="Mission 2" score="7"></challenge>
<challenge title="Mission 3" score="9"></challenge>
<average average="6"/>
</player>
</game>
Result xml2.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?><game>
<player nickname="Rooney">
<challenge score="10" title="Mission 1"/>
<challenge score="5" title="Mission 2"/>
<challenge score="7" title="Mission 3"/>
<average average="7,33"/>
</player>
<player nickname="Doc">
<challenge score="5" title="Mission 1"/>
<challenge score="2" title="Mission 2"/>
<challenge score="8" title="Mission 3"/>
<average average="5,00"/>
</player>
<player nickname="Junior">
<challenge score="10" title="Mission 1"/>
<challenge score="3" title="Mission 2"/>
<challenge score="5" title="Mission 3"/>
<average average="6,00"/>
</player>
<player nickname="Candice">
<challenge score="1" title="Mission 1"/>
<challenge score="7" title="Mission 2"/>
<challenge score="9" title="Mission 3"/>
<average average="5,67"/>
</player>
</game>
Java code
import java.io.*;
import org.w3c.dom.*;
import java.text.DecimalFormat;
import org.xml.sax.SAXException;
import javax.xml.parsers.*;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class Parser{
public static void main(String[] args) throws TransformerConfigurationException, TransformerException {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbf.newDocumentBuilder();
//Building DOM tree
Document doc = dBuilder.parse("C:\\xml1.xml");
Parser obj = new Parser();
obj.parseDocument(doc);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
public void parseDocument(Document document) throws TransformerConfigurationException, TransformerException {
//Getting the root element
Node gameRoot = document.getDocumentElement();
NodeList playersNodeList = gameRoot.getChildNodes();
for (int i = 0; i < playersNodeList.getLength(); i++) {
Node player = playersNodeList.item(i);
if (!(player instanceof Element)) {
continue;
}
double avgScore = 0;
double sum = 0;
int scoreCount = 0;
//Printing out player's nicknames
NamedNodeMap playerAttributes = player.getAttributes();
for (int l = 0; l < playerAttributes.getLength(); l++) {
Attr attr = (Attr) playerAttributes.item(l);
if ("nickname".equals(attr.getName())) {
System.out.println(attr.getValue());
}
}
NodeList playersChildNodes = player.getChildNodes();
//Iterate through each player's child nodes
for (int j = 0; j < playersChildNodes.getLength(); j++) {
if (!(playersChildNodes.item(j) instanceof Element)) {
continue;
}
Element element = (Element) playersChildNodes.item(j);
//Getting attributes from player's child nodes
NamedNodeMap nnm = element.getAttributes();
for (int a = 0; a < nnm.getLength(); a++) {
Attr attr = (Attr) nnm.item(a);
//If attribute's name is "score", parse its value to Double and add to the sum
if ("score".equals(attr.getName())) {
sum += Double.parseDouble(attr.getValue());
scoreCount++;
}
// If attribute's name is "average", count the average score
if ("average".equals(attr.getName())) {
avgScore = (scoreCount == 0) ? 0 : sum / scoreCount;
DecimalFormat decimalFormat = new DecimalFormat("0.00");
System.out.println("Old Average Score Value was: " + attr.getValue() + "." + " New Average Score Value is: " + avgScore + ".");
attr.setValue(decimalFormat.format(avgScore));
}
}
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource src = new DOMSource(document);
StreamResult result = new StreamResult(new File("xml2.xml"));
transformer.transform(src, result);
}
}
}