DOM Processing
Posted on February 9, 2007
Suppose that we need to process an XML document:
<?xml version=”1.0″?> <purchaseOrder orderDate=”19991020″> <shipTo country=”US”> <name>Alice Smith</name> <street>123 Maple Street</street> <city>Mill Valley</city> <state>CA</state> <zip>90952</zip> </shipTo> <billTo country=”US”> <name>Robert Smith</name> <street>8 Oak Avenue</street> <city>Old Town</city> <state>PA</state> <zip>95819</zip> </billTo> <comment>Hurry, my lawn is going wild!</comment> <items> <item partNum=”872AA”> <productName>Lawnmower</productName> <quantity>1</quantity> <USPrice>148.95</USPrice> <comment>Confirm this is electricWe need to collect the partNum attributes and compute the sum of the prices in the USPrice elements. In Java we can do this for example using DOM:import org.w3c.dom.Document; import org.w3c.dom.Element; ... //Retrieve the Document object DocumentBuilder fact = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document po = fact.parse(new File("po.xml")); Element root = po.getDocumentElement(); //Retrieve all partNums and compute the grand total for the purchase order double total = 0; NodeList children = root.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node node = children.item(i); //Find the items child element if ("items".equals(node.getLocalName())) { NodeList itemList = node.getChildNodes(); for (int j = 0; j < itemList.getLength(); j++) { Node item = itemList.item(j); //Get the partNum attribute value NamedNodeMap attrs = item.getAttributes(); System.out.println("partNum:" + attrs.getNamedItem("partNum")); //Find the USPrice child element NodeList itemChildren = item.getChildNodes(); for (int k = 0; k < itemChildren.getLength(); k++) { Node child = itemChildren.item(k); if ("USPrice".equals(child.getLocalName()) { total += Double.valueOf(child.getNodeValue()).doubleValue(); } } } } } System.out.println("Grand total = " + total);We can do the same thing in Scala, but in a much simplier way:
import scala.xml.XML;
val doc = XML.loadFile("po.xml");
var total = 0;
for(val z <- doc \\ "item";
val y <- z \ "USPrice") {
Console.println("partnum: " + z \ "@partNum");
total = total + Double.valueOf(y.text)
}
Console.println("Grand total " + total);And according to the documentation, Scala implementation uses half the the memory of DOM model.
Example is from Scalable Programming Abstractions for XML Services.
Filed Under Uncategorized |
1 Comment so farLeave a Comment
If you would like to make a comment, please fill out the form below.
I did some XML processing recently with HPricot in ruby. Your example would look something like this:
require ‘Hpricot’
doc = HPricot(open(’po.xml’))
sum = 0
doc.search(’item’) do |item|
puts item.search(’productname’).first
sum += item.search(’usprice’).first.to_f * item.search(’quantity’).first.to_i
end
If you instead had tags like
<item partNum=”xxx” price=”39.99″ qty=”2″ /> you would access that like this:
doc.search(’item’) do |item|
puts item[’productname’]
sum += item[’usprice’].to_f * item[’quantity’].to_i
end