macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Applying "Digital Hub" Concepts to Enterprise Software Design, Part 4
Pages: 1, 2, 3, 4, 5, 6

Add XML Parsing

Getting data out of the database is great, but we also need a way to get data back in! Let's add XML parsing to our application. First, add the following import statements to the beginning of the XML.java file:

import javax.xml.parsers.*;
import org.xml.sax.*;
import java.io.*;

Then add the following methods to the XML class:

public static void addNewData(String theXml) {
  XML.addNewData(new InputSource(new StringReader(theXml)));
}

public static void addNewData(InputSource inSource) {
  SAXParserFactory factory =
  SAXParserFactory.newInstance();
        
  try {            
    SAXParser saxParser = factory.newSAXParser();
    XMLReader parser = saxParser.getXMLReader();
            
    parsingClass ch = new parsingClass();
            
    parser.setContentHandler(ch);
            
    parser.parse(inSource);
            
  } catch (Throwable t) {
     t.printStackTrace();  
    }
}

There are two methods here. One takes an XML string and the other takes the XML as a Java InputSource. As you can see, the second really does all the work. The reason we have the method that takes a string is that this method will be easier to call from a web service.

The parser code is fairly straightforward. We create a parser using the Java class parsingClass (which we will create in a moment). Then we send the XML to the parser. The exciting work of extracting data from the XML and adding it to the database will take place in the parsingClass file, so let's add it now.

  1. Right click (or Ctrl-click) the Classes folder in the left panel of your project (you may need to expand the WeatherHub group) and choose Add -> New File...

  2. Under the WebObjects section, choose the "Java Class" type and click Next.

  3. Name the file parsingClass.java and check the box next to Application Server in the Targets selector. Make sure that none of the other targets are selected, and click Finish.

  4. Set the contents of parsingClass.java to the following:

import com.webobjects.foundation.*;
import com.webobjects.eocontrol.*;

import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class parsingClass extends DefaultHandler {    

  public void startElement(String namespace,
                           String localname,
                           String qname,
                           Attributes atts){
    if ( qname.equals("item") ) {
      String id = "";
      String data = "";
      String measurementTypeId = "";
      String timeTaken = "";
      //slurp all the attributes to java variables
      for (int i=0; i < atts.getLength(); i++) {                    
        if (atts.getQName(i).equals("id")) {
          id = atts.getValue(i);  
        }else if(atts.getQName(i).equals("data")){
          data = atts.getValue(i);  
        }else if (atts.getQName(i).equals("typeId")){
          measurementTypeId = atts.getValue(i);  
        }else if(atts.getQName(i).equals("time")){
          timeTaken = atts.getValue(i);  
        }  
      }
      //if an item has a blank ID 
      //we should add it to the database
      if ( id.equals("") ) {
        //create a data item and add it to the database
     System.out.println("Adding data item to the database");
        EOClassDescription dataDesc = 
        EOClassDescription.classDescriptionForEntityName(
                                            "MeasuredData");
        EOEditingContext editingContext = 
        new EOEditingContext();
        EOGenericRecord newDataItem =
        new EOGenericRecord(dataDesc);
                
        newDataItem.takeValueForKey(data, "data");
        newDataItem.takeValueForKey(measurementTypeId,
                                    "measurementTypeId");
                
        NSTimestampFormatter formatter = 
        new NSTimestampFormatter("%Y-%m-%d %H:%M:%S %z");

        try{
          newDataItem.takeValueForKey(
              (NSTimestamp)formatter.parseObject(timeTaken),
              "timeTaken");
        } catch (java.text.ParseException e) {
          System.out.println("error parsing timeTaken " + 
                             "date");  
        }

        editingContext.insertObject(newDataItem);
                
        editingContext.saveChanges(); 
      }  
    }
  }
}

For those who would prefer to download the code, here is a link (parsingClass.java).

To parse the XML file, we are overloading the DefaultHandler class of org.xml.sax. For this particular example, we only need to overload one method, startElement. The parser will start at the top of the file and will call this method each time a starting tag is encountered in the XML. Because we are storing all of our data in XML attributes as opposed to storing it between tags, this is sufficient. Check out the Java documentation for DefaultHandler for other methods you can use to parse more complex XML formats.

I assumed that we would not be adding new measureTypes by parsing XML. Remember that we built an administration tool in part two that could handle this task. Instead, to keep this tutorial as simple as possible, the method only adds data item information to the database. That is why most of the code is wrapped in an if statement that checks for an item XML tag.

When an item tag is found, the for loop iterates through all of the XML attributes and saves them into local variables that will be easy for us to refer to. Next, the code needs to decide whether the current node is new or not (we are only going to add new nodes, not allow modification of existing nodes). The code does this by checking for an id attribute. Since id numbers are assigned when an attribute is added to the database, we will assume that a data item without an id has not yet been added to the database.

If our data item is new, the remaining code creates a new item with WebObjects, assigns all of the attribute values that we captured from the XML, and then adds it to the database.

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow