You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Dan Tarkenton <ta...@gmail.com> on 2004/07/26 23:15:46 UTC

[Digester] basic usage problem. Help me understand the stack.

Hello, I've used Digester a few times in the past with much success. 
Mostly, I've parsed XML documents and simply grabbed the attributes,
and not the body text.  I was looking through the documentation at
http://jakarta.apache.org/commons/digester/api/ the digester package
specifically.  When I came across the example of parsing the web.xml
file to grab body text.  I figured, hey, this should be easy.

I have an xml document that has several elements named Part.  I
essentially want to parse the XML document and create a collection of
Parts.  Simple, right?  Well, I'm embarrased to say I can't figure out
why I only get one Part object in my resulting Hashtable when I run
the Digester.  And I can't figure out why only the first Part element
in my document is the one that shows up.  So I figure i'm not parsing
recursively or something.

Here's my BOMParser class:

package com.titan.bat.parsers.ise;

import com.titan.bat.util.MessageUtil;
import com.titan.bat.util.MessageResourcesKeys;
import com.titan.bat.exception.BOMParserException;
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXParseException;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Enumeration;

/**
 * @author dant
 * @version $Id$
 */
public class BOMParser implements MessageResourcesKeys {

    public static Hashtable getParts() {
        return parts;
    }

    private static Hashtable parts = new Hashtable();
    /**
     * TODO - Change parsing to accept String, not File
     *
     **/
    public void parse(String document) throws BOMParserException {

        Digester digester = initializeParser();
        //BOMParser resultsParser = null;
        try {

        //resultsParser = (BOMParser)digester.parse(new StringReader(document));
        digester.parse(new
File("/usr/local/projects/BOMAnalysis/web/xml/psbk.xml"));
        } catch (SAXParseException saxe) {
	    	String msg =
MessageUtil.formatMessage(MSG_FULLY_INDENTED_BOM_PARSER_FAILURE);
	    	throw new BOMParserException(msg, saxe);
    	} catch (SAXException saxe) {
	    	String msg =
MessageUtil.formatMessage(MSG_FULLY_INDENTED_BOM_PARSER_FAILURE);
	    	throw new BOMParserException(msg, saxe);
    	} catch (IOException ioe) {
	    	String msg = MessageUtil.formatMessage(MSG_FULLY_INDENTED_BOM_IO_FAILURE);
	    	throw new BOMParserException(msg, ioe);

    	}
    }

    /**
     * Initializes the parsing rules for the Apache Digester parser.
     **/
    public Digester initializeParser() {

	    // instantiate Digester and enable XML validation
        Digester digester = new Digester();

        digester.push(this);
        digester.setErrorHandler(new BOMParserErrorHandler());
        digester.setValidating(true);

        // instantiate BOMParser class
        //digester.addObjectCreate("product", BOMParser.class );
        digester.addObjectCreate("product/component/part",
"com.titan.bat.parsers.ise.Part" );

        //digester.addCallMethod("product/component/quantity",
"setQuantity", 0);
        //digester.addCallMethod("product/component/refDesignators/refDes",
"addRefDes", 0);
        digester.addCallMethod("product/component/part/partNumber",
"setPartNumber", 0);
        digester.addCallMethod("product/component/part/partDescription",
"setPartDescription", 0);
        digester.addCallMethod("product/component/part/partMaterialCode",
"setPartMaterialCode", 0);
        digester.addCallMethod("product/component/part/partUM", "setPartUM", 0);
        digester.addCallMethod("product/component/part/partSpecHandling/SpecCode",
"addSpecCode", 0);
        digester.addSetNext("product/component/part", "addPart" );
        return digester;
    }


    public void addPart(Part part) {
        parts.put(part.getPartNumber(), part);
    }

    public static void main (String args[]) {

        BOMParser parser = new BOMParser();
        parser.initializeParser();
        try {
            parser.parse("foo");
        } catch (BOMParserException e) {
            e.printStackTrace();
        }
        Hashtable parts = parser.getParts();
        Enumeration x = parts.keys();
        while (x.hasMoreElements()) {
            String partNumber = (String)x.nextElement();
            System.out.println("partnumber = " + partNumber);
            Part part = (Part)parts.get(partNumber);
            System.out.println("PartDescription = " +
part.getPartDescription());
            System.out.println("Part Material Code = " +
part.getPartMaterialCode());
            System.out.println("Part UM = " + part.getPartUM());
        }
    }
}

I suppose I have configured the digester incorrectly in the
initialize() method.

Anyone seeing the obvious that I'm not seeing?  

Thanks in advance.

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Simon Kitching <si...@ecnetwork.co.nz>.
On Tue, 2004-07-27 at 09:15, Dan Tarkenton wrote:
> Hello, I've used Digester a few times in the past with much success. 
> Mostly, I've parsed XML documents and simply grabbed the attributes,
> and not the body text.  I was looking through the documentation at
> http://jakarta.apache.org/commons/digester/api/ the digester package
> specifically.  When I came across the example of parsing the web.xml
> file to grab body text.  I figured, hey, this should be easy.
> 
> I have an xml document that has several elements named Part.  I
> essentially want to parse the XML document and create a collection of
> Parts.  Simple, right?  Well, I'm embarrased to say I can't figure out
> why I only get one Part object in my resulting Hashtable when I run
> the Digester.  And I can't figure out why only the first Part element
> in my document is the one that shows up.  So I figure i'm not parsing
> recursively or something.

You may wish to have a look at the code in the "examples" directory in
CVS. These examples cover many of the basic tasks Digester can be used
for.

In particular, the "addressbook" and "catalog" examples may be useful.

http://cvs.apache.org/viewcvs.cgi/jakarta-commons/digester/src/examples/api/

Regards,

Simon



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Dan Tarkenton <ta...@gmail.com>.
So after typing up that reply I realize that my refDes property in
Part.java was null.  Once I turned that into an initialized
Collection, it worked as I thought.  Oh well, maybe someone will find
some use in that code.

Sorry to spam the list ;)

On Tue, 27 Jul 2004 14:06:46 -0400, Dan Tarkenton <ta...@gmail.com> wrote:
> Perhaps I spoke too soon in my last response.  I would like to have a
> look at the chains source you spoke of for configuration however when
> I visit http://jakarta.apache.org/commons/chain/ there is a note
> stating the source is unreleased.  Do I need to go to CVS to grab the
> src?
> 
> I did however to manage to get recursion to work in my code with the
> */part idea.  I'll post that code below, but first my issue:
> 
> I have run into another behavioral issue that I do not understand; the
> problem revolves around the digester.addCallMethod method.  My
> understanding is that this method calls a method on the top (parent)
> object.  Since the only object I ever deal with in my stack is
> Part.java, I will go ahead and show that code:
> 
> public class Part {
> 
>     public ArrayList getParts() {
>         return parts;
>     }
> 
>     private ArrayList parts = new ArrayList();
> 
>     private String partNumber;
>     private String partDescription;
>     private String partMaterialCode;
>         private String partUM;
>         private String quantity;
>     private Vector refDes;
>         private Vector specCodes;
> 
>     public String getPartNumber() {
>         return partNumber;
>     }
> 
>     public void setPartNumber(String partNumber) {
>         this.partNumber = partNumber;
>     }
> 
>     public Vector getSpecCodes() {
>         return specCodes;
>     }
> 
>     public void setSpecCodes(Vector specCodes) {
>         this.specCodes = specCodes;
>     }
> 
>     public Vector getRefDes() {
>         return refDes;
>     }
> 
>     public void setRefDes(Vector refDes) {
>         this.refDes = refDes;
>     }
> 
>     public String getQuantity() {
>         return quantity;
>     }
> 
>     public void setQuantity(String quantity) {
>         this.quantity = quantity;
>     }
> 
>     public String getPartUM() {
>         return partUM;
>     }
> 
>     public void setPartUM(String partUM) {
>         this.partUM = partUM;
>     }
> 
>     public String getPartMaterialCode() {
>         return partMaterialCode;
>     }
> 
>     public void setPartMaterialCode(String partMaterialCode) {
>         this.partMaterialCode = partMaterialCode;
>     }
> 
>     public String getPartDescription() {
>         return partDescription;
>     }
> 
>     public void setPartDescription(String partDescription) {
>         this.partDescription = partDescription;
>     }
> 
>     public boolean isValidSpecCode(String specCode) {
>         //TODO find out valid spec codes
>         return true;
>     }
> 
>     public void addRefDes(String refDes) {
>         if (refDes == null) return;
>         this.refDes.add(refDes);
>     }
> 
>     public void addSpecCode(String specCode) {
>         this.specCodes.add(specCode);
>     }
> 
>     public void addPart(Part part) {
>         parts.add(part);
>     }
> }
> 
> Note that this class has addPart(Part part) and addRefDes(String
> refDes).  Now when I run my Parser code (below) with the exception of
> the addCallMethod line, I get the Part objects I need.  However, when
> i have digester.addCallMethod("*/component/refDesignators/refDes",
> "addRefDes", 0); in my code, I get a null pointer.  What I don't
> understand is that Part object has addRefDes(String x) method.  The
> way I've written it, every object in the stack is always a part
> object, correct?  So why does the addCallMethod call not grab the body
> text of the refDes element and add it to my Part object?
> 
> public void parse(String document) throws ParserException {
> 
>         Digester digester = new Digester();
> 
>         digester.setErrorHandler(new BOMParserErrorHandler());
>         digester.setValidating(true);
>         digester.addObjectCreate("*/component", Part.class );
> 
>         digester.addBeanPropertySetter( "*/component/quantity", "quantity");
>         digester.addCallMethod("*/component/refDesignators/refDes",
> "addRefDes", 0);  //this line is my culprit
> 
>         digester.addBeanPropertySetter( "*/component/part/partNumber",
> "partNumber");
>         digester.addBeanPropertySetter(
> "*/component/part/partDescription", "partDescription");
>         digester.addBeanPropertySetter(
> "*/component/part/partMaterialCode", "partMaterialCode");
>         digester.addBeanPropertySetter( "*/component/part/partUM", "partUM");
>         digester.addSetNext("*/component", "addPart",
> "com.titan.bat.parsers.ise.Part");
> 
>         Part dummy = new Part();
>         digester.push(dummy);
> 
>         try {
>             digester.parse(new
> File("/usr/local/projects/BOMAnalysis/web/xml/psbk.xml"));
>         } 
>             //catch exceptions
>         }
> 
>         Iterator iter = dummy.getParts().iterator();
>         Part part;
>         while (iter.hasNext()) {
>             part = (Part) iter.next();
>             parts.put(part.getPartNumber(), part);
>         }
> 
>         this.addPart(dummy);
>     }
> 
>     public void addPart(Part root) {
> 
>        Part part;
>        if (root.getParts() !=null || root.getParts().size() > 0) {
> //has children
>            System.out.println("part #" + root.getPartNumber() + " has
> children");
>            Iterator iter = root.getParts().iterator();
>            while (iter.hasNext()) {
>                 part = (Part) iter.next();
>                 System.out.println("part.getRefDes() = " + part.getRefDes());
>                 if (part !=null && part.getPartNumber() !=null) {
>                     parts.put(part.getPartNumber(), part);
>                     this.addPart(part);
>                 }
> 
>            }
>        }
>     }
> 
> Anyone have any insight as to why that addCallMethod is blowing up my code?
> 
> Thanks,
> Dan
>

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by rich coco <ra...@starbak.com>.
my guess is the Part object has already been popped from the stack by the time
the 'refDes' element is hit?

Dan Tarkenton wrote:
> Perhaps I spoke too soon in my last response.  I would like to have a
> look at the chains source you spoke of for configuration however when
> I visit http://jakarta.apache.org/commons/chain/ there is a note
> stating the source is unreleased.  Do I need to go to CVS to grab the
> src?
> 
> I did however to manage to get recursion to work in my code with the
> */part idea.  I'll post that code below, but first my issue:
> 
> I have run into another behavioral issue that I do not understand; the
> problem revolves around the digester.addCallMethod method.  My
> understanding is that this method calls a method on the top (parent)
> object.  Since the only object I ever deal with in my stack is
> Part.java, I will go ahead and show that code:
> 
> public class Part {
> 
>     public ArrayList getParts() {
>         return parts;
>     }
> 
>     private ArrayList parts = new ArrayList();
> 
>     private String partNumber;
>     private String partDescription;
>     private String partMaterialCode;
> 	private String partUM;
> 	private String quantity;
>     private Vector refDes;
> 	private Vector specCodes;
> 
>     public String getPartNumber() {
>         return partNumber;
>     }
> 
>     public void setPartNumber(String partNumber) {
>         this.partNumber = partNumber;
>     }
> 
>     public Vector getSpecCodes() {
>         return specCodes;
>     }
> 
>     public void setSpecCodes(Vector specCodes) {
>         this.specCodes = specCodes;
>     }
> 
>     public Vector getRefDes() {
>         return refDes;
>     }
> 
>     public void setRefDes(Vector refDes) {
>         this.refDes = refDes;
>     }
> 
>     public String getQuantity() {
>         return quantity;
>     }
> 
>     public void setQuantity(String quantity) {
>         this.quantity = quantity;
>     }
> 
>     public String getPartUM() {
>         return partUM;
>     }
> 
>     public void setPartUM(String partUM) {
>         this.partUM = partUM;
>     }
> 
>     public String getPartMaterialCode() {
>         return partMaterialCode;
>     }
> 
>     public void setPartMaterialCode(String partMaterialCode) {
>         this.partMaterialCode = partMaterialCode;
>     }
> 
>     public String getPartDescription() {
>         return partDescription;
>     }
> 
>     public void setPartDescription(String partDescription) {
>         this.partDescription = partDescription;
>     }
> 
>     public boolean isValidSpecCode(String specCode) {
>         //TODO find out valid spec codes
>         return true;
>     }
> 
>     public void addRefDes(String refDes) {
>         if (refDes == null) return;
>         this.refDes.add(refDes);
>     }
> 
>     public void addSpecCode(String specCode) {
>         this.specCodes.add(specCode);
>     }
> 
>     public void addPart(Part part) {
>         parts.add(part);
>     }
> }
> 
> Note that this class has addPart(Part part) and addRefDes(String
> refDes).  Now when I run my Parser code (below) with the exception of
> the addCallMethod line, I get the Part objects I need.  However, when
> i have digester.addCallMethod("*/component/refDesignators/refDes",
> "addRefDes", 0); in my code, I get a null pointer.  What I don't
> understand is that Part object has addRefDes(String x) method.  The
> way I've written it, every object in the stack is always a part
> object, correct?  So why does the addCallMethod call not grab the body
> text of the refDes element and add it to my Part object?
> 
> public void parse(String document) throws ParserException {
> 
>         Digester digester = new Digester();
> 
>         digester.setErrorHandler(new BOMParserErrorHandler());
>         digester.setValidating(true);
>         digester.addObjectCreate("*/component", Part.class );
> 
>         digester.addBeanPropertySetter( "*/component/quantity", "quantity");
>         digester.addCallMethod("*/component/refDesignators/refDes",
> "addRefDes", 0);  //this line is my culprit
> 
>         digester.addBeanPropertySetter( "*/component/part/partNumber",
> "partNumber");
>         digester.addBeanPropertySetter(
> "*/component/part/partDescription", "partDescription");
>         digester.addBeanPropertySetter(
> "*/component/part/partMaterialCode", "partMaterialCode");
>         digester.addBeanPropertySetter( "*/component/part/partUM", "partUM");
>         digester.addSetNext("*/component", "addPart",
> "com.titan.bat.parsers.ise.Part");
> 
>         Part dummy = new Part();
>         digester.push(dummy);
> 
>         try {
>             digester.parse(new
> File("/usr/local/projects/BOMAnalysis/web/xml/psbk.xml"));
>         } 
>             //catch exceptions
>     	}
> 
>         Iterator iter = dummy.getParts().iterator();
>         Part part;
>         while (iter.hasNext()) {
>             part = (Part) iter.next();
>             parts.put(part.getPartNumber(), part);
>         }
> 
>         this.addPart(dummy);
>     }
> 
>     public void addPart(Part root) {
> 
>        Part part;
>        if (root.getParts() !=null || root.getParts().size() > 0) {
> //has children
>            System.out.println("part #" + root.getPartNumber() + " has
> children");
>            Iterator iter = root.getParts().iterator();
>            while (iter.hasNext()) {
>                 part = (Part) iter.next();
>                 System.out.println("part.getRefDes() = " + part.getRefDes());
>                 if (part !=null && part.getPartNumber() !=null) {
>                     parts.put(part.getPartNumber(), part);
>                     this.addPart(part);
>                 }
> 
>            }
>        }
>     }
> 
> Anyone have any insight as to why that addCallMethod is blowing up my code?
> 
> Thanks,
> Dan
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org

-- 
rich coco
racoco@starbak.com
781.736.1200  x165
Starbak Inc.
29 Sawyer Rd.
One University Office Park
Waltham, MA 02453


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Dan Tarkenton <ta...@gmail.com>.
Thanks.  Will have a look.

On Tue, 27 Jul 2004 11:48:01 -0700, Craig McClanahan <cr...@gmail.com> wrote:
> On Tue, 27 Jul 2004 14:06:46 -0400, Dan Tarkenton <ta...@gmail.com> wrote:
> > Perhaps I spoke too soon in my last response.  I would like to have a
> > look at the chains source you spoke of for configuration however when
> > I visit http://jakarta.apache.org/commons/chain/ there is a note
> > stating the source is unreleased.  Do I need to go to CVS to grab the
> > src?
> 
> You can use CVS, or grab a nightly build:
> 
>   http://cvs.apache.org/builds/jakarta-commons/nightly/commons-chain/
> 
> 
> 
> Craig
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org
> 
>

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Craig McClanahan <cr...@gmail.com>.
On Tue, 27 Jul 2004 14:06:46 -0400, Dan Tarkenton <ta...@gmail.com> wrote:
> Perhaps I spoke too soon in my last response.  I would like to have a
> look at the chains source you spoke of for configuration however when
> I visit http://jakarta.apache.org/commons/chain/ there is a note
> stating the source is unreleased.  Do I need to go to CVS to grab the
> src?

You can use CVS, or grab a nightly build:

  http://cvs.apache.org/builds/jakarta-commons/nightly/commons-chain/

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Dan Tarkenton <ta...@gmail.com>.
Perhaps I spoke too soon in my last response.  I would like to have a
look at the chains source you spoke of for configuration however when
I visit http://jakarta.apache.org/commons/chain/ there is a note
stating the source is unreleased.  Do I need to go to CVS to grab the
src?

I did however to manage to get recursion to work in my code with the
*/part idea.  I'll post that code below, but first my issue:

I have run into another behavioral issue that I do not understand; the
problem revolves around the digester.addCallMethod method.  My
understanding is that this method calls a method on the top (parent)
object.  Since the only object I ever deal with in my stack is
Part.java, I will go ahead and show that code:

public class Part {

    public ArrayList getParts() {
        return parts;
    }

    private ArrayList parts = new ArrayList();

    private String partNumber;
    private String partDescription;
    private String partMaterialCode;
	private String partUM;
	private String quantity;
    private Vector refDes;
	private Vector specCodes;

    public String getPartNumber() {
        return partNumber;
    }

    public void setPartNumber(String partNumber) {
        this.partNumber = partNumber;
    }

    public Vector getSpecCodes() {
        return specCodes;
    }

    public void setSpecCodes(Vector specCodes) {
        this.specCodes = specCodes;
    }

    public Vector getRefDes() {
        return refDes;
    }

    public void setRefDes(Vector refDes) {
        this.refDes = refDes;
    }

    public String getQuantity() {
        return quantity;
    }

    public void setQuantity(String quantity) {
        this.quantity = quantity;
    }

    public String getPartUM() {
        return partUM;
    }

    public void setPartUM(String partUM) {
        this.partUM = partUM;
    }

    public String getPartMaterialCode() {
        return partMaterialCode;
    }

    public void setPartMaterialCode(String partMaterialCode) {
        this.partMaterialCode = partMaterialCode;
    }

    public String getPartDescription() {
        return partDescription;
    }

    public void setPartDescription(String partDescription) {
        this.partDescription = partDescription;
    }

    public boolean isValidSpecCode(String specCode) {
        //TODO find out valid spec codes
        return true;
    }

    public void addRefDes(String refDes) {
        if (refDes == null) return;
        this.refDes.add(refDes);
    }

    public void addSpecCode(String specCode) {
        this.specCodes.add(specCode);
    }

    public void addPart(Part part) {
        parts.add(part);
    }
}

Note that this class has addPart(Part part) and addRefDes(String
refDes).  Now when I run my Parser code (below) with the exception of
the addCallMethod line, I get the Part objects I need.  However, when
i have digester.addCallMethod("*/component/refDesignators/refDes",
"addRefDes", 0); in my code, I get a null pointer.  What I don't
understand is that Part object has addRefDes(String x) method.  The
way I've written it, every object in the stack is always a part
object, correct?  So why does the addCallMethod call not grab the body
text of the refDes element and add it to my Part object?

public void parse(String document) throws ParserException {

        Digester digester = new Digester();

        digester.setErrorHandler(new BOMParserErrorHandler());
        digester.setValidating(true);
        digester.addObjectCreate("*/component", Part.class );

        digester.addBeanPropertySetter( "*/component/quantity", "quantity");
        digester.addCallMethod("*/component/refDesignators/refDes",
"addRefDes", 0);  //this line is my culprit

        digester.addBeanPropertySetter( "*/component/part/partNumber",
"partNumber");
        digester.addBeanPropertySetter(
"*/component/part/partDescription", "partDescription");
        digester.addBeanPropertySetter(
"*/component/part/partMaterialCode", "partMaterialCode");
        digester.addBeanPropertySetter( "*/component/part/partUM", "partUM");
        digester.addSetNext("*/component", "addPart",
"com.titan.bat.parsers.ise.Part");

        Part dummy = new Part();
        digester.push(dummy);

        try {
            digester.parse(new
File("/usr/local/projects/BOMAnalysis/web/xml/psbk.xml"));
        } 
            //catch exceptions
    	}

        Iterator iter = dummy.getParts().iterator();
        Part part;
        while (iter.hasNext()) {
            part = (Part) iter.next();
            parts.put(part.getPartNumber(), part);
        }

        this.addPart(dummy);
    }

    public void addPart(Part root) {

       Part part;
       if (root.getParts() !=null || root.getParts().size() > 0) {
//has children
           System.out.println("part #" + root.getPartNumber() + " has
children");
           Iterator iter = root.getParts().iterator();
           while (iter.hasNext()) {
                part = (Part) iter.next();
                System.out.println("part.getRefDes() = " + part.getRefDes());
                if (part !=null && part.getPartNumber() !=null) {
                    parts.put(part.getPartNumber(), part);
                    this.addPart(part);
                }

           }
       }
    }

Anyone have any insight as to why that addCallMethod is blowing up my code?

Thanks,
Dan

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by rich coco <ra...@starbak.com>.
yes, this makes sense.
i may be on the verge of seeing how it might work for what i
am trying to do.

Bill Keese wrote:
>>>it does not seem to me the "*/part" type of pattern will work.
>>>this approach does not keep the correspondence between a <part> strucuture
>>>and its parent container(s).
>>>   
>>>
> 
> I might be wrong, but I think that this is just a simple
> misunderstanding. Apparently, you are thinking that
> 
> digester.addObjectCreate("*/part", "mypackage.Part");
> 
> will create a flat list of parts, rather than a (hierarchical) tree. But
> that's not the case.
> 
> 
>>// Set up the digester
>>Digester digester = ...;
>>digester.addObjectCreate("*/part", "mypackage.Part");
>>digester.addSetProperties("*/part");
>>digester.addSetNext("*/part", "addPart", "mypackage.Part");
>>
>>// Push a dummy Part onto the stack to collect all the top-level parts
>>Part dummy = new Part();
>>digester.push(dummy);
> 
> 
> At this point, stack=(dummy).
> 
> 
>>// Parse the XML document
>>digester.parse(...);
> 
> 
>>1 <parts>
>>2 <part id="1">
>>3 </part>
>>4 <part id="2">
>>5 <part id="2a">
>>6 </part>
>>7 </part>
>>8 </parts>
> 
> 
> 
> When you call parse, here's what digester does as it processes each line
> of the input XML file:
> 
> Line 2:
> - stack.push(new Part(id=1))
> 
> stack = (dummy, part#1)
> 
> Line 3:
> - dummy.addPart(stack.pop()) <-- add part#1 as child of dummy
> 
> stack = (dummy)
> 
> Line 4:
> - stack.push(new Part(id=2))
> 
> stack = (dummy, part#2)
> 
> Line 5:
> - stack.push(new Part(id=2a))
> 
> stack = (dummy, part#2, part#2a) <-- hierarchy is correct, right?
> 
> Line 6:
> - part#2.addPart(stack.pop()) <-- this makes part#2a a child of part#2
> 
> stack = (dummy, part#2)
> 
> Line 7:
> - dummy.addPart(stack.pop()) <-- add part#2 as child of dummy
> 
> stack = (dummy)
> 
> Does that make sense?
> 
> Bill
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org

-- 
rich coco
racoco@starbak.com
781.736.1200  x165
Starbak Inc.
29 Sawyer Rd.
One University Office Park
Waltham, MA 02453


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Bill Keese <bi...@tech.beacon-it.co.jp>.
>>it does not seem to me the "*/part" type of pattern will work.
>>this approach does not keep the correspondence between a <part> strucuture
>>and its parent container(s).
>>    
>>
I might be wrong, but I think that this is just a simple
misunderstanding. Apparently, you are thinking that

digester.addObjectCreate("*/part", "mypackage.Part");

will create a flat list of parts, rather than a (hierarchical) tree. But
that's not the case.

> // Set up the digester
> Digester digester = ...;
> digester.addObjectCreate("*/part", "mypackage.Part");
> digester.addSetProperties("*/part");
> digester.addSetNext("*/part", "addPart", "mypackage.Part");
>
> // Push a dummy Part onto the stack to collect all the top-level parts
> Part dummy = new Part();
> digester.push(dummy);

At this point, stack=(dummy).

>
> // Parse the XML document
> digester.parse(...);

> 1 <parts>
> 2 <part id="1">
> 3 </part>
> 4 <part id="2">
> 5 <part id="2a">
> 6 </part>
> 7 </part>
> 8 </parts>


When you call parse, here's what digester does as it processes each line
of the input XML file:

Line 2:
- stack.push(new Part(id=1))

stack = (dummy, part#1)

Line 3:
- dummy.addPart(stack.pop()) <-- add part#1 as child of dummy

stack = (dummy)

Line 4:
- stack.push(new Part(id=2))

stack = (dummy, part#2)

Line 5:
- stack.push(new Part(id=2a))

stack = (dummy, part#2, part#2a) <-- hierarchy is correct, right?

Line 6:
- part#2.addPart(stack.pop()) <-- this makes part#2a a child of part#2

stack = (dummy, part#2)

Line 7:
- dummy.addPart(stack.pop()) <-- add part#2 as child of dummy

stack = (dummy)

Does that make sense?

Bill

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Craig McClanahan <cr...@gmail.com>.
On Tue, 27 Jul 2004 13:24:00 +1200, Simon Kitching
<si...@ecnetwork.co.nz> wrote:
> On Tue, 2004-07-27 at 13:17, Rich Coco wrote:
> >
> > Suppose you need to parse the xml and return, say, a hashtable
> > containing the associated java objects.
> >

In other words you want to flatten the hierarchy?  That doesn't seem
like something you *have* to do while parsing (if you do, then you
might need some custom Digester rules -- doable, but more work). 
Instead, assuming the Part data structure that I identified in my
earlier response, you can create a flattened Map after the parse
completes, like this:

    Part dummy = ... the dummy part from earlier ...
    Map flattened = new HashMap();
    Iterator parts = dummy.getParts().iterator();
    while (parts.hasNext()) {
        flatten(flattened, (Part) parts.next());
    }


    // Private method that recursively flattens a part structure
    private void flatten(Map map, Part part) {
        // Add this part to the map
        map.put(new Integer(part.getId()), part);
        // Add the sub-parts of this part to the map recursively
        Iterator parts = part.getParts();
        while (parts.hasNext()) {
            flatten(map, (Part) parts.next());
        }
    }

With an extra "if" statement, you can do things like check for
duplicate part ids, if that is needed.

The extra loop in the main body of the code is based on the assumption
that the dummy top-level Part isn't a "real" Part ... it's just a
collector.  If it is real (in other words, if the entire BOM you are
parsing is to construct a single assembly), the main line code is even
simpler:

    Part dummy = ... the dummy part from earlier ...
    Map flattened = new HashMap();
    flatten(flattened, dummy);

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Simon Kitching <si...@ecnetwork.co.nz>.
On Tue, 2004-07-27 at 14:06, Rich Coco wrote:
> I'd like to do this with *one* Digester servlet,
> not one specialized Digester servlet per xmlrpc method.
> (the latter would not be hard to do. why am i making htis hard on myself?
> Hmmmmm...)

Maybe you should look at the xmlrules module, where the parsing rules
can be defined in an xml-format config file?

This way, you can have a single "servlet", and instantiate a digester
using whichever xmlrules config file is appropriate for the input
message.

This is equivalent to having a bunch of different classes to do the
parsing, except that you can handle new structures by adding config
files instead of classes.

Note, however, that I still think your original problem can be handled
by a single set of rules.

Regards,

Simon




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Rich Coco <ra...@starbak.com>.
unfortunately, for me, i *do* have to keep the containment hierarchy
intact. the incoming xmlrpc msg is a method call and its
incoming arguments - which can have arbitrarily nested structures
within structures, arrays of structures as structure elements, etc... -
have to be presented to a java class that handles that particular method
call in such a way that the java objects built from the xmlrpc method
args  maintain the original 'containment' relationship.

so for example, suppose xmlrpc method Foo has these three arguments:
Struct_1, Struct_2, Array(Struct_3) > I am trying to avoid using xml here.
Struct_1 is some strucuture definition, as is Struct_2,
and then the 3rd arg is an array of structures (each memeber being of
type Struct_2, some other know structure definition).

then the result of parsing such xml code would have to be, say, a hashtable
something like this:

Arg_1_name  ==>  new Struct_1( ... )  // args are known member/values
Arg_2_name ==> new Struct_2(...)
Arg_3_Name ==>  new Vector<Struct_3>

any of the above structures could conceivably contain another structure
as an element. the Arg names are knwon from the original XML spec defining
the API. this spec specifies all Structure definitions and all Method
signatures.

it is relatively straight-forward (using digester) to parse such xml definitions to generated:
  * java classes for each structure definition

  * java classes for each method that takes one or more of the strucutre
     definitions as an argument (or Vectors thereof).

  * each Structure class has its custom (generated) toXML() method so that
    an instantiated such class can output its xmlrpc fragment. Such fragments
    can be concatentated together - together with a methodName - to form
    a well-fromed xmlrpc message which can be *sent* over the wire.

What I am finding much more difficult to do is the reverse:
take an *incoming* xmlrpc request (with a specified methodRequest name
already known from the XML input spec file from which everything is generated)
and turn its xmlrpc arguments (which are the nested structure definitions
for which we have well defined java class definitions) into a container
(hashtable?) of java classes that can be handed to the java class
(not generated) that handles this specific request.

I'd like to do this with *one* Digester servlet,
not one specialized Digester servlet per xmlrpc method.
(the latter would not be hard to do. why am i making htis hard on myself?
Hmmmmm...)




Simon Kitching wrote:
> On Tue, 2004-07-27 at 13:17, Rich Coco wrote:
> 
> 
> If you need to treat Part objects differently depending upon their
> parent element, then you can use these patterns:
>   */struct_1/part
>   */struct_2/part
>   */part/part
> 
> Here, I presume that when processing a part nested within a part, it
> doesn't matter what the parent of the top-level part is. I can't imagine
> a scenario where this would not be the desired behaviour.
> 
> Regards,
> 
> Simon
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Simon Kitching <si...@ecnetwork.co.nz>.
On Tue, 2004-07-27 at 13:17, Rich Coco wrote:
> but what if a Part object could be member of other objects 
> that are represented as xml elements, eg, consider an xmlrpc 
> msg fragment:
> 
> <struct>
>   <member>
>     <name>Struct_1</name>
>     <value>
>       <array>
>          <data>
>            <value>
>              <struct>
>                <member>
>                  <name>Struct_2</name>
> .  .  .
> 
> 
> Struct_1 can contain a Part element (not shown).
> It also contains an array of Struct_2 elements,
> one of whose members can either be a Part or another
> structure containing a Part, etc...
> 
> Suppose you need to parse the xml and return, say, a hashtable
> containing the associated java objects.
> 
> you may assume you know a priori the definitions for all 
> structure types (in xml). and assume you even have alreay generated
> Java class definition for each such structure. (not hard using digester
> if you have an input spec (in xml of course) defining the strucures,
> giving them a name, specifying the members and their types, etc...
> 
> it does not seem to me the "*/part" type of pattern will work.
> this approach does not keep the correspondence between a <part> strucuture
> and its parent container(s).
> 
> it's a gnarly problem me thinks...one i eventually have to solve.

If you need to treat Part objects differently depending upon their
parent element, then you can use these patterns:
  */struct_1/part
  */struct_2/part
  */part/part

Here, I presume that when processing a part nested within a part, it
doesn't matter what the parent of the top-level part is. I can't imagine
a scenario where this would not be the desired behaviour.

Regards,

Simon


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Rich Coco <ra...@starbak.com>.
but what if a Part object could be member of other objects 
that are represented as xml elements, eg, consider an xmlrpc 
msg fragment:

<struct>
  <member>
    <name>Struct_1</name>
    <value>
      <array>
         <data>
           <value>
             <struct>
               <member>
                 <name>Struct_2</name>
.  .  .


Struct_1 can contain a Part element (not shown).
It also contains an array of Struct_2 elements,
one of whose members can either be a Part or another
structure containing a Part, etc...

Suppose you need to parse the xml and return, say, a hashtable
containing the associated java objects.

you may assume you know a priori the definitions for all 
structure types (in xml). and assume you even have alreay generated
Java class definition for each such structure. (not hard using digester
if you have an input spec (in xml of course) defining the strucures,
giving them a name, specifying the members and their types, etc...

it does not seem to me the "*/part" type of pattern will work.
this approach does not keep the correspondence between a <part> strucuture
and its parent container(s).

it's a gnarly problem me thinks...one i eventually have to solve.

- rich

Craig McClanahan wrote: 

> Actually, there's a fairly straightforward and elegant solution to
> this sort of problem, if you have control over the object types being
> constructed.  For example, assume you have something like this,
> representing a part (say, in a bill of materials explosion) that has
> sub-parts:
> 
>     package mypackage;
> 
>     import java.util.ArrayList;
>     import java.util.List;
> 
>     pubic class Part {
> 
>         // An "id" property for this part
>         private String partId;
>         public String getPartId() { return partId; }
>         pubic vod setPartId(String partId) { this.partId = partId; }
> 
>         // Add a new sub-part for this part
>         public void addPart(Part part) {
>             parts.add(part);
>         }
> 
>         // Retrieve the sub-parts for this part
>         private List parts = new ArrayList();
>         public List getParts() {
>             return parts;
>         }
> 
>     }
> 
> Now, you can construct a recursive hierarchy of parts with some very
> simple Digester rules (assuming you push onto the stack an empty part
> to collect all the top-level children):
> 
>     // Set up the digester
>     Digester digester = ...;
>     digester.addObjectCreate("*/part", "mypackage.Part");
>     digester.addSetProperties("*/part");
>     digester.addSetNext("*/part", "addPart", "mypackage.Part");
> 
>     // Push a dummy Part onto the stack to collect all the top-level parts
>     Part dummy = new Part();
>     digester.push(dummy);
> 
>     // Parse the XML document
>     digester.parse(...);
> 
>     // Now, process the top-level parts we parsed
>     Iterator parts = dummy.getParts().iterator();
>     while (parts.hasNext()) {
>         Part part = (Part) parts.next();
>         ...
>     }
> 
> And you can deal with arbitrarily nested part hierarchies:
> 
>     <parts>
>         <part ...>
>         </part>
>         <part ...>
>             <part .../>
>             <part .../>
>         </part>
>     </parts>
> 
>>good lucj
>>
>>- rich
> 
> 
> Craig
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Dan Tarkenton <ta...@gmail.com>.
Craig, thanks again, man.  You've helped me several times in the past
on the struts list.  I see exactly what I was missing.  Pushing that
dummy Part object to the top of the digester stack makes perfect sense
now that you wrote it out for me -- well that and adding the addPart
method to the Part class for recursion purposes.  That solution is so
obvious yet I couldn't wrap my head around it all day today.

Thanks again.

/Dan

On Mon, 26 Jul 2004 17:34:59 -0700, Craig McClanahan <cr...@gmail.com> wrote:
> On Mon, 26 Jul 2004 18:40:48 -0400, Rich Coco <ra...@starbak.com> wrote:
> > if you are simply trying to caoture all occurrences
> > of <part>, the the pattern you want is "*/part" i believe.
> > It will find that element at all depths.
> 
> Yes, this is quite useful.
> 
> In addition to the examples that Simon pointed you at, you might want
> to grab a build of the Commons "chain" sources.  In the
> org.apache.commons.chain.config package, you'll see a use of Digester
> that leverages the "*/part" style to deal with recursive configuration
> file structures.  A simplified version of this idea is presented
> below.
> 
> >
> > however, if you care about *where* the <part> element occurs -
> > eg, if it is (recursively) embedded inside other elements that you
> > you also have to tuen, say, into java objects of which a collection of
> > Part objects is a member (and maybe this higher level object is
> > embedded in an even higher level object that is represented by an
> > xml element) - then you have a much harder problem.
> >
> > I am confronting it myself, but have had to turn my attention away
> > from it for the next week or so. i would be delighted to hear if you
> > implement a truly recursive solution. i'd like to steal it!
> > (at least the implementation design part of it).
> >
> 
> Actually, there's a fairly straightforward and elegant solution to
> this sort of problem, if you have control over the object types being
> constructed.  For example, assume you have something like this,
> representing a part (say, in a bill of materials explosion) that has
> sub-parts:
> 
>     package mypackage;
> 
>     import java.util.ArrayList;
>     import java.util.List;
> 
>     pubic class Part {
> 
>         // An "id" property for this part
>         private String partId;
>         public String getPartId() { return partId; }
>         pubic vod setPartId(String partId) { this.partId = partId; }
> 
>         // Add a new sub-part for this part
>         public void addPart(Part part) {
>             parts.add(part);
>         }
> 
>         // Retrieve the sub-parts for this part
>         private List parts = new ArrayList();
>         public List getParts() {
>             return parts;
>         }
> 
>     }
> 
> Now, you can construct a recursive hierarchy of parts with some very
> simple Digester rules (assuming you push onto the stack an empty part
> to collect all the top-level children):
> 
>     // Set up the digester
>     Digester digester = ...;
>     digester.addObjectCreate("*/part", "mypackage.Part");
>     digester.addSetProperties("*/part");
>     digester.addSetNext("*/part", "addPart", "mypackage.Part");
> 
>     // Push a dummy Part onto the stack to collect all the top-level parts
>     Part dummy = new Part();
>     digester.push(dummy);
> 
>     // Parse the XML document
>     digester.parse(...);
> 
>     // Now, process the top-level parts we parsed
>     Iterator parts = dummy.getParts().iterator();
>     while (parts.hasNext()) {
>         Part part = (Part) parts.next();
>         ...
>     }
> 
> And you can deal with arbitrarily nested part hierarchies:
> 
>     <parts>
>         <part ...>
>         </part>
>         <part ...>
>             <part .../>
>             <part .../>
>         </part>
>     </parts>
> 
> > good lucj
> >
> > - rich
> 
> Craig
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org
> 
>

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Craig McClanahan <cr...@gmail.com>.
On Mon, 26 Jul 2004 18:40:48 -0400, Rich Coco <ra...@starbak.com> wrote:
> if you are simply trying to caoture all occurrences
> of <part>, the the pattern you want is "*/part" i believe.
> It will find that element at all depths.

Yes, this is quite useful.

In addition to the examples that Simon pointed you at, you might want
to grab a build of the Commons "chain" sources.  In the
org.apache.commons.chain.config package, you'll see a use of Digester
that leverages the "*/part" style to deal with recursive configuration
file structures.  A simplified version of this idea is presented
below.

> 
> however, if you care about *where* the <part> element occurs -
> eg, if it is (recursively) embedded inside other elements that you
> you also have to tuen, say, into java objects of which a collection of
> Part objects is a member (and maybe this higher level object is
> embedded in an even higher level object that is represented by an
> xml element) - then you have a much harder problem.
> 
> I am confronting it myself, but have had to turn my attention away
> from it for the next week or so. i would be delighted to hear if you
> implement a truly recursive solution. i'd like to steal it!
> (at least the implementation design part of it).
> 

Actually, there's a fairly straightforward and elegant solution to
this sort of problem, if you have control over the object types being
constructed.  For example, assume you have something like this,
representing a part (say, in a bill of materials explosion) that has
sub-parts:

    package mypackage;

    import java.util.ArrayList;
    import java.util.List;

    pubic class Part {

        // An "id" property for this part
        private String partId;
        public String getPartId() { return partId; }
        pubic vod setPartId(String partId) { this.partId = partId; }

        // Add a new sub-part for this part
        public void addPart(Part part) {
            parts.add(part);
        }

        // Retrieve the sub-parts for this part
        private List parts = new ArrayList();
        public List getParts() {
            return parts;
        }

    }

Now, you can construct a recursive hierarchy of parts with some very
simple Digester rules (assuming you push onto the stack an empty part
to collect all the top-level children):

    // Set up the digester
    Digester digester = ...;
    digester.addObjectCreate("*/part", "mypackage.Part");
    digester.addSetProperties("*/part");
    digester.addSetNext("*/part", "addPart", "mypackage.Part");

    // Push a dummy Part onto the stack to collect all the top-level parts
    Part dummy = new Part();
    digester.push(dummy);

    // Parse the XML document
    digester.parse(...);

    // Now, process the top-level parts we parsed
    Iterator parts = dummy.getParts().iterator();
    while (parts.hasNext()) {
        Part part = (Part) parts.next();
        ...
    }

And you can deal with arbitrarily nested part hierarchies:

    <parts>
        <part ...>
        </part>
        <part ...>
            <part .../>
            <part .../>
        </part>
    </parts>

> good lucj
> 
> - rich

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Re: [Digester] basic usage problem. Help me understand the stack.

Posted by Rich Coco <ra...@starbak.com>.
if you are simply trying to caoture all occurrences
of <part>, the the pattern you want is "*/part" i believe.
It will find that element at all depths.

however, if you care about *where* the <part> element occurs -
eg, if it is (recursively) embedded inside other elements that you
you also have to tuen, say, into java objects of which a collection of
Part objects is a member (and maybe this higher level object is
embedded in an even higher level object that is represented by an
xml element) - then you have a much harder problem.

I am confronting it myself, but have had to turn my attention away
from it for the next week or so. i would be delighted to hear if you
implement a truly recursive solution. i'd like to steal it!
(at least the implementation design part of it).

good lucj

- rich

Dan Tarkenton wrote:
> Hello, I've used Digester a few times in the past with much success. 
> Mostly, I've parsed XML documents and simply grabbed the attributes,
> and not the body text.  I was looking through the documentation at
> http://jakarta.apache.org/commons/digester/api/ the digester package
> specifically.  When I came across the example of parsing the web.xml
> file to grab body text.  I figured, hey, this should be easy.
> 
> I have an xml document that has several elements named Part.  I
> essentially want to parse the XML document and create a collection of
> Parts.  Simple, right?  Well, I'm embarrased to say I can't figure out
> why I only get one Part object in my resulting Hashtable when I run
> the Digester.  And I can't figure out why only the first Part element
> in my document is the one that shows up.  So I figure i'm not parsing
> recursively or something.
> 
> Here's my BOMParser class:
> 
> package com.titan.bat.parsers.ise;
> 
> import com.titan.bat.util.MessageUtil;
> import com.titan.bat.util.MessageResourcesKeys;
> import com.titan.bat.exception.BOMParserException;
> import org.apache.commons.digester.Digester;
> import org.xml.sax.SAXParseException;
> import org.xml.sax.SAXException;
> 
> import java.io.File;
> import java.io.IOException;
> import java.util.Hashtable;
> import java.util.Enumeration;
> 
> /**
>  * @author dant
>  * @version $Id$
>  */
> public class BOMParser implements MessageResourcesKeys {
> 
>     public static Hashtable getParts() {
>         return parts;
>     }
> 
>     private static Hashtable parts = new Hashtable();
>     /**
>      * TODO - Change parsing to accept String, not File
>      *
>      **/
>     public void parse(String document) throws BOMParserException {
> 
>         Digester digester = initializeParser();
>         //BOMParser resultsParser = null;
>         try {
> 
>         //resultsParser = (BOMParser)digester.parse(new StringReader(document));
>         digester.parse(new
> File("/usr/local/projects/BOMAnalysis/web/xml/psbk.xml"));
>         } catch (SAXParseException saxe) {
> 	    	String msg =
> MessageUtil.formatMessage(MSG_FULLY_INDENTED_BOM_PARSER_FAILURE);
> 	    	throw new BOMParserException(msg, saxe);
>     	} catch (SAXException saxe) {
> 	    	String msg =
> MessageUtil.formatMessage(MSG_FULLY_INDENTED_BOM_PARSER_FAILURE);
> 	    	throw new BOMParserException(msg, saxe);
>     	} catch (IOException ioe) {
> 	    	String msg = MessageUtil.formatMessage(MSG_FULLY_INDENTED_BOM_IO_FAILURE);
> 	    	throw new BOMParserException(msg, ioe);
> 
>     	}
>     }
> 
>     /**
>      * Initializes the parsing rules for the Apache Digester parser.
>      **/
>     public Digester initializeParser() {
> 
> 	    // instantiate Digester and enable XML validation
>         Digester digester = new Digester();
> 
>         digester.push(this);
>         digester.setErrorHandler(new BOMParserErrorHandler());
>         digester.setValidating(true);
> 
>         // instantiate BOMParser class
>         //digester.addObjectCreate("product", BOMParser.class );
>         digester.addObjectCreate("product/component/part",
> "com.titan.bat.parsers.ise.Part" );
> 
>         //digester.addCallMethod("product/component/quantity",
> "setQuantity", 0);
>         //digester.addCallMethod("product/component/refDesignators/refDes",
> "addRefDes", 0);
>         digester.addCallMethod("product/component/part/partNumber",
> "setPartNumber", 0);
>         digester.addCallMethod("product/component/part/partDescription",
> "setPartDescription", 0);
>         digester.addCallMethod("product/component/part/partMaterialCode",
> "setPartMaterialCode", 0);
>         digester.addCallMethod("product/component/part/partUM", "setPartUM", 0);
>         digester.addCallMethod("product/component/part/partSpecHandling/SpecCode",
> "addSpecCode", 0);
>         digester.addSetNext("product/component/part", "addPart" );
>         return digester;
>     }
> 
> 
>     public void addPart(Part part) {
>         parts.put(part.getPartNumber(), part);
>     }
> 
>     public static void main (String args[]) {
> 
>         BOMParser parser = new BOMParser();
>         parser.initializeParser();
>         try {
>             parser.parse("foo");
>         } catch (BOMParserException e) {
>             e.printStackTrace();
>         }
>         Hashtable parts = parser.getParts();
>         Enumeration x = parts.keys();
>         while (x.hasMoreElements()) {
>             String partNumber = (String)x.nextElement();
>             System.out.println("partnumber = " + partNumber);
>             Part part = (Part)parts.get(partNumber);
>             System.out.println("PartDescription = " +
> part.getPartDescription());
>             System.out.println("Part Material Code = " +
> part.getPartMaterialCode());
>             System.out.println("Part UM = " + part.getPartUM());
>         }
>     }
> }
> 
> I suppose I have configured the digester incorrectly in the
> initialize() method.
> 
> Anyone seeing the obvious that I'm not seeing?  
> 
> Thanks in advance.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-user-help@jakarta.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org