DigesterLazyDynaBean

HomePage | RecentChanges | Preferences

This is an example of parsing XML into a List of LazyDynaBeans?. I plan to use it to present a "resolution list" in my web application. This is a list of possible matches displayed after the user enters a person's name.

If you're looking for the example that goes with my 1/28/05 post to commons-user, this one is similar but not exactly the same.

There doesn't seem to be a way to set a true indexed property with Digester. Without writing a custom Rule, I don't see how you'd use the setProp(int,String) method. (Which is not to say I _know_ how to write a rule that would do it...)

Example XML

<resolution>
  <person key="0423540">
    <preferredName>Ms. Mary J. Smith</preferredName>
    <birthName>Brown</birthName>
    <status>Deceased</status>
    <address>
      <line>545 Atlanta Ave.</line>
      <line>Normal, IL 12345</line>
    </address>
    <birthDate>05/21/1921</birthDate>
    <source>Alumnus</source>
    <reunionClass>MD1941</reunionClass>
  </person>
  <person key="0520273">
    <preferredName>Ms. Marienne J. Krupac</preferredName>
    <birthName>Smithers</birthName>
    <status></status>
    <address>
      <line>123 State Street</line>
      <line>Phoenix, AZ 82123</line>
    </address>
    <birthDate>05/21/1949</birthDate>
    <source>Friend of Alumni</source>
    <reunionClass>MB1971</reunionClass>
  </person>
</resolution>

The code:

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.beanutils.LazyDynaBean;
import org.apache.commons.digester.*;


/**
 * @author    Wendy Smoak
 */
public class Main {

   /**
    *  The main program for the Main class
    *
    * @param  args  The command line arguments
    */
   public static void main(String[] args) {

      try {
         Digester digester = new Digester();
         digester.setValidating(false);

         /*
          *  When the 'resolution' tag is found, create an ArrayList
          *  and push it on the stack
          */
         digester.addObjectCreate("resolution", ArrayList.class);

         /*
          *  When the 'download' tag is found, create a LazyDynaBean
          *  and push it on the stack
          */
         digester.addObjectCreate("resolution/person", LazyDynaBean.class);

         /*
          *  Set the properties for all attributes of <person>
          */
         digester.addSetProperties("resolution/person");

         /*
          *  Set the properties for all nested tags of <person>
          *  except the ones that should be ignored.
          */
         String[] propertyNames = new String[]{"address"};
         String[] elementNames = new String[]{null};
         digester.addSetNestedProperties("resolution/person", propertyNames, elementNames);

         /*
          *  deal separately with address as it cannot be set as a
          *  simple nested property
          */
         digester.addObjectCreate("resolution/person/address", ArrayList.class);
         digester.addCallMethod("resolution/person/address/line", "add", 1);
         digester.addCallParam("resolution/person/address/line", 0);

         int stackPosition = 1;
         int numParams = 2;
         Rule rule = new CallMethodRule(stackPosition, "set", numParams);
         digester.addRule("resolution/person/address", rule);
         //The param 0 is the literal string "address"
         digester.addObjectParam("resolution/person/address", 0, "address");
         boolean fromStack = true;
         digester.addCallParam("resolution/person/address", 1, fromStack);

//NOTE:  The '1' in the previous line might need to be a '-1'

         /*
          *  When we hit the closing </person> tag, call ArrayList.add
          */
         digester.addSetNext("resolution/person", "add");

         File inputFile = new File(args[0]);

         List list = (List) digester.parse(inputFile);
         Iterator iter = list.iterator();
         while (iter.hasNext()) {
            System.out.println(((LazyDynaBean) iter.next()).getMap());
         }

      } catch (Exception exc) {
         exc.printStackTrace();
      }

   }

}

The Output

E:\java\digester>ant run
Buildfile: build.xml

compile:
    [javac] Compiling 1 source file to E:\java\digester

run:
     [java] {key=0423540, reunionClass=MD1941, preferredName=Ms. Mary J. Smith,
address=[545 Atlanta Ave., Normal, IL 12345], birthName=Brown, status=Deceased,
source=Alumnus, birthDate=05/21/1921}
     [java] {key=0520273, reunionClass=MB1971, preferredName=Ms. Marienne J. Kru
pac, address=[123 State Street, Phoenix, AZ 82123], birthName=Smithers, status=,
 source=Friend of Alumni, birthDate=05/21/1949}

BUILD SUCCESSFUL
Total time: 2 seconds
E:\java\digester>

HomePage | RecentChanges | Preferences
This page is read-only | View other revisions
Last edited February 7, 2005 12:19 pm by wsmoak.vpia.asu.edu (diff)
Search: