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 electric

We 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 far
  1. Guillaume March 6, 2007 10:45 pm

    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

Leave a Comment

If you would like to make a comment, please fill out the form below.

Name

Email

Website

Comments

For spam detection purposes, please copy the number 5390 to the field below:

© Copyright 0xDEADBEEFCAFE • Powered by Wordpress • Design by Sebastin.

free web hit counter