Task:
You have got an XML file "company.xml" that looks like this:
<?xml version="1.0"?>
<company>
<employee>
<firstname>Tom</firstname>
<lastname>Cruise</lastname>
</employee>
<employee>
<firstname>Paul</firstname>
<lastname>Enderson</lastname>
</employee>
<employee>
<firstname>George</firstname>
<lastname>Bush</lastname>
</employee>
</company>
You have to read this file and print the firstName
and lastName
fields of all the employees.
Java: [ taken from here ]
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
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 XmlReader {
public static void main(String[] args) {
try {
File file = new File("company.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
NodeList nodeLst = doc.getElementsByTagName("employee");
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
Element fstElmnt = (Element) fstNode;
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("firstname");
Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
NodeList fstNm = fstNmElmnt.getChildNodes();
System.out.println("First Name: " + ((Node) fstNm.item(0)).getNodeValue());
NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("lastname");
Element lstNmElmnt = (Element) lstNmElmntLst.item(0);
NodeList lstNm = lstNmElmnt.getChildNodes();
System.out.println("Last Name: " + ((Node) lstNm.item(0)).getNodeValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Scala: [ taken from here, slide #19 ]
import xml.XML
object XmlReader {
def main(args: Array[String]): Unit = {
XML.loadFile("company.xml") match {
case <employee> { employees @ _* } </employee> => {
for(e <- employees) {
println("First Name: " + (e \ "firstname").text)
println("Last Name: " + (e \ "lastname").text)
}
}
}
}
}
[ EDIT by Bill; Check comments for the discussion ] --
Hmm, how to do it without replying in an unformatted reply section... Hmph. I guess I'll edit your answer and let you delete it if it bugs you.
This is how I would do it in Java with better libraries:
public scanForEmployees(String filename) {
GoodXMLLib source=new GoodXMLLib(filename);
while( String[] employee: source.scanFor("employee", "firstname", "lastname") )
{
System.out.println("First Name: " + employee[0]);
System.out.println("Last Name: " + employee[1]);
}
}
This is just a quick hack involving no magic and all reusable components. If I wanted to add some magic I could do something better than returning an array of string arrays, but even as is this GoodXMLLib would be completely reusable. The first parameter of scanFor is the section, all future parameters would be the items to find which is limited, but the interface could be buffed slightly to add multiple levels of matching with no real problem.
I will admit that Java has some pretty poor library support in general, but come on--to compare a horrible usage of Java's decade(?) old XML library to an implementation done based on being terse is just not fair--and is far from a comparison of the languages!