You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Philip A Grim II <pg...@data-tactics.com> on 2010/10/01 21:12:42 UTC

[digester] Trouble adding a list to a hash map

I'm having difficulty with the Digester when trying to add a list to a hash
map.

The following is a portion of the XML I'm digesting:

 

<?xml version=\"1.0\" encoding=\"utf-8\"?>

<Envelope>

  <Person>

    <Locations>

      <Location>

        <Id>3eca4cd1-a07a-4013-b4a3-1d6a6530f7e3</Id>

        <DateAsOf>201007132112</DateAsOf>

        <DateLastModified>20100803203509203</DateLastModified>

        <Name>Most Recent Location</Name>

        <WKT>POINT (69.568583399873617 33.86775960347174 0)</WKT>

      </Location>

      <Location>

        <Id>3e2462d1-a0c7-4013-4523-1345a3b8f7e3</Id>

        <DateAsOf>201007100814</DateAsOf>

        <DateLastModified>20100803203509203</DateLastModified>

        <Name>Previous Location</Name>

        <WKT>POINT (66.53455434533617 32.863453455537174 0)</WKT>

      </Location>

    </Locations>

  </Person>

</Envelope>

 

The top level object is a HashMap that contains properties of the Person
tag.  Simple properties work fine, but nested properties such as Locations
are what are giving me trouble.  I am trying to create an ArrayList of the
Location tags which contains a HashMap of the properties nested inside each
Location tag, and that part works, but when I try to add that ArrayList to
the HashMap of person properties, I get an empty list.

 

Please note that I have no control over the format of the XML itself...it is
created by a third-party application, and I have to read what's there.

 

Attached is a simple code example that shows what I've tried to do.  Either
I'm doing it wrong or something isn't happening the way it should in the
Digester.  I'd appreciate any help you could offer.

 

Thanks,

Phil

 

 

 

 

Philip A Grim II
Chief Engineer
Data Tactics Corporation
7901 Jones Branch Dr.
Suite 240
McLean, VA  22102

Cell: (717) 880-1714

cid:1257801836.2381.12.camel@dt-pg.dt-pbj.org

The information contained in this message may be privileged and/or
confidential and protected from disclosure.  If the reader of this message
is not the intended recipient or an employee or agent responsible for
delivering this message to the intended recipient, you are hereby notified
that any dissemination, distribution or copying of this communication is
strictly prohibited.  If you have received this communication in error,
please notify the sender immediately by replying to this message and
deleting the material from any computer.



 


RE: [digester] Trouble adding a list to a hash map

Posted by Philip A Grim II <pg...@data-tactics.com>.
Again, my apologies for the length of my post.

You have solved the problem.  

Many thanks,

Phil

-----Original Message-----
From: Rahul Akolkar [mailto:rahul.akolkar@gmail.com] 
Sent: Friday, October 01, 2010 10:09 PM
To: Commons Users List
Subject: Re: [digester] Trouble adding a list to a hash map

Please note that its important to post the smallest piece of code that
fully demonstrates the problem at hand -- vast majority of the code
below is quite unrelated and it takes time to read through each line
that you add to your post.

In any case, I did find atleast a couple of needles in the haystack.
Given the length of the email, I've added markers to my inline
comments, search for the string "RA:" in this email to get to my
comments below.




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


Re: [digester] Trouble adding a list to a hash map

Posted by Rahul Akolkar <ra...@gmail.com>.
Please note that its important to post the smallest piece of code that
fully demonstrates the problem at hand -- vast majority of the code
below is quite unrelated and it takes time to read through each line
that you add to your post.

In any case, I did find atleast a couple of needles in the haystack.
Given the length of the email, I've added markers to my inline
comments, search for the string "RA:" in this email to get to my
comments below.

On Fri, Oct 1, 2010 at 4:37 PM, Philip A Grim II <pg...@data-tactics.com> wrote:
> Apologies...wasn't thinking straight.
>
> Here's the code.
>
> import java.io.ByteArrayInputStream;
> import java.io.IOException;
> import java.util.ArrayList;
> import java.util.HashMap;
> import java.util.Map;
>
> import org.apache.commons.digester.Digester;
> import org.apache.commons.digester.xmlrules.DigesterLoader;
> import org.xml.sax.InputSource;
> import org.xml.sax.SAXException;
>
> public class DigestTester
> {
>  private static String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
>                              "<Envelope>" +
>                              "  <Person>" +
>                              "    <Locations>" +
>                              "      <Location>" +
>                              "
> <Id>3eca4cd1-a07a-4013-b4a3-1d6a6530f7e3</Id>" +
>                              "        <DateAsOf>201007132112</DateAsOf>" +
>                              "
> <DateLastModified>20100803203509203</DateLastModified>" +
>                              "        <Name>Most Recent Location</Name>" +
>                              "        <WKT>POINT (69.568583399873617
> 33.86775960347174 0)</WKT>" +
>                              "      </Location>" +
>                              "      <Location>" +
>                              "
> <Id>3e2462d1-a0c7-4013-4523-1345a3b8f7e3</Id>" +
>                              "        <DateAsOf>201007100814</DateAsOf>" +
>                              "
> <DateLastModified>20100803203509203</DateLastModified>" +
>                              "        <Name>Previous Location</Name>" +
>                              "        <WKT>POINT (66.53455434533617
> 32.863453455537174 0)</WKT>" +
>                              "      </Location>" +
>                              "    </Locations>" +
>                              "  </Person>" +
>                              "</Envelope>";
>
>
>  private static String test2 = "<?xml version=\"1.0\"?>" +
>                                   "<digester-rules>" +
<snip/>

RA: Meta point is that when using XML rules its best to use an XML
editor, reference the DTD and inspect / validate the rules before
trying to use them. When used as a Java string such as above, it can
hide problems as I'll point out below.



>                                   "<pattern value=\"Envelope/Person\">" +
>                                   "<object-create-rule
> pattern=\"Locations\" classname=\"java.util.ArrayList\"/>" +
>                                   "<object-create-rule
> pattern=\"Locations/Location\" classname=\"java.util.HashMap\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/Id\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"id\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/DateAsOf\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_as_of\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/DateLastModified\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_last_modified\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"name\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"1\"/>" +
>                                   "<call-method-rule
> pattern=\"Locations/Location/WKT\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                   "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                   "<object-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"wkt\"/>" +
>                                   "<call-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"1\"/>" +
>                                   "<set-next-rule
> pattern=\"Locations/Location\" methodname=\"add\"/>" +
>                                   "</pattern>" +
>                                   "</digester-rules>";
>
>
>  private static String test3 = "<?xml version=\"1.0\"?>" +
>                                    "<digester-rules>" +
>                                    "<pattern value=\"Envelope/Person\">" +
>                                    "<object-create-rule
> pattern=\"Locations\" classname=\"java.util.ArrayList\"/>" +
>                                    "<object-create-rule
> pattern=\"Locations/Location\" classname=\"java.util.HashMap\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/Id\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"id\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/Id\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/DateAsOf\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_as_of\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/DateLastModified\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_last_modified\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/DateLastModified\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"name\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/Name\" paramnumber=\"1\"/>" +
>                                    "<call-method-rule
> pattern=\"Locations/Location/WKT\" targetoffset=\"0\" methodname=\"put\"
> paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"wkt\"/>" +
>                                    "<call-param-rule
> pattern=\"Locations/Location/WKT\" paramnumber=\"1\"/>" +
>                                    "<set-next-rule
> pattern=\"Locations/Location\" methodname=\"add\"/>" +
>                                    "<call-method-rule pattern=\"Locations\"
> targetoffset=\"1\" methodname=\"put\" paramcount=\"2\"" +
>                                    "
> paramtypes=\"java.lang.String,java.util.ArrayList\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations\" paramnumber=\"0\" type=\"java.lang.String\"
> value=\"locations\"/>" +
>                                    "<object-param-rule
> pattern=\"Locations\" paramnumber=\"1\" type=\"java.util.ArrayList\"
> fromstack=\"true\"/>" +
<snap/>

RA: Above line should contain:

<call-param-rule pattern=\"Locations\" paramnumber=\"1\"
type=\"java.util.ArrayList\" from-stack=\"true\"/>

i.e. use <call-param-rule> and use correct attribute name "from-stack".



>                                    "</pattern>" +
>                                    "</digester-rules>";
>
>  private static String test4 = "<?xml version=\"1.0\"?>" +
>                                "<digester-rules>" +
>                                "<pattern value=\"Envelope\">" +
>                                "<object-create-rule pattern=\"Person\"
> classname=\"java.util.HashMap\"/>" +
>                                "<object-create-rule
> pattern=\"Person/Locations\" classname=\"java.util.ArrayList\"/>" +
>                                "<object-create-rule
> pattern=\"Person/Locations/Location\" classname=\"java.util.HashMap\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/Id\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/Id\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"id\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/Id\" paramnumber=\"1\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/DateAsOf\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/DateAsOf\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_as_of\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/DateLastModified\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/DateLastModified\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"date_last_modified\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/DateLastModified\" paramnumber=\"1\"/>"
> +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/Name\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/Name\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/Name\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"name\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/Name\" paramnumber=\"1\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations/Location/WKT\" targetoffset=\"0\"
> methodname=\"put\" paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations/Location/WKT\" paramnumber=\"0\"
> type=\"java.lang.String\" value=\"wkt\"/>" +
>                                "<call-param-rule
> pattern=\"Person/Locations/Location/WKT\" paramnumber=\"1\"/>" +
>                                "<set-next-rule
> pattern=\"Person/Locations/Location\" methodname=\"add\"/>" +
>                                "<call-method-rule
> pattern=\"Person/Locations\" targetoffset=\"1\" methodname=\"put\"
> paramcount=\"2\"" +
>                                "
> paramtypes=\"java.lang.String,java.util.ArrayList\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations\" paramnumber=\"0\" type=\"java.lang.String\"
> value=\"locations\"/>" +
>                                "<object-param-rule
> pattern=\"Person/Locations\" paramnumber=\"1\" type=\"java.util.ArrayList\"
> fromstack=\"true\"/>" +
<snip/>

RA: Above line should contain:

<call-param-rule pattern=\"Person/Locations\" paramnumber=\"1\"
type=\"java.util.ArrayList\" from-stack=\"true\"/>

i.e. use <call-param-rule> and use correct attribute name "from-stack".

-Rahul



>                                "</pattern>" +
>                                "</digester-rules>";
>
>
>  @SuppressWarnings("unchecked")
>  public static void main(String[] args)
>  {
>    // First version, just make a list that contains a hash map.
>    // This works, and values show up.
>    System.out.println("----------------------- First Test
> ---------------------------");
>    ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes());
>    Digester digester = new Digester();
>    digester.setValidating(false);
>
>    digester.addObjectCreate("Envelope/Person/Locations",
> "java.util.ArrayList");
>    digester.addObjectCreate("Envelope/Person/Locations/Location",
> "java.util.HashMap");
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/Id", "put",
> 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/Id", 0,
> "id");
>    digester.addCallParam("Envelope/Person/Locations/Location/Id", 1);
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/DateAsOf",
> "put", 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/DateAsOf",
> 0, "date_as_of");
>    digester.addCallParam("Envelope/Person/Locations/Location/DateAsOf", 1);
>
>
> digester.addCallMethod("Envelope/Person/Locations/Location/DateLastModified"
> , "put", 2, new String[] { "java.lang.String", "java.lang.Object" });
>
> digester.addObjectParam("Envelope/Person/Locations/Location/DateLastModified
> ", 0, "date_last_modified");
>
> digester.addCallParam("Envelope/Person/Locations/Location/DateLastModified",
> 1);
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/Name", "put",
> 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/Name", 0,
> "name");
>    digester.addCallParam("Envelope/Person/Locations/Location/Name", 1);
>
>    digester.addCallMethod("Envelope/Person/Locations/Location/WKT", "put",
> 2, new String[] { "java.lang.String", "java.lang.Object" });
>    digester.addObjectParam("Envelope/Person/Locations/Location/WKT", 0,
> "wkt");
>    digester.addCallParam("Envelope/Person/Locations/Location/WKT", 1);
>
>    digester.addSetNext("Envelope/Person/Locations/Location", "add");
>
>    try
>    {
>      ArrayList results = (ArrayList)digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object item : results)
>      {
>        if (item instanceof Map)
>        {
>          System.out.println("    Item:");
>          for(Object tag : ((Map)item).keySet())
>          {
>            System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>          }
>        }
>        else
>        {
>          System.err.println("Item was not a map: " + item);
>        }
>      }
>
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>
>    // Second version, just make a list that contains a hash map, using
> xmlrules.
>    // This works, and values show up.
>    System.out.println("----------------------- Second Test
> ---------------------------");
>    stream = new ByteArrayInputStream(xml.getBytes());
>    digester = DigesterLoader.createDigester(new InputSource(new
> ByteArrayInputStream(test2.getBytes())));
>    digester.setValidating(false);
>    try
>    {
>      ArrayList results = (ArrayList)digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object item : results)
>      {
>        if (item instanceof Map)
>        {
>          System.out.println("    Item:");
>          for(Object tag : ((Map)item).keySet())
>          {
>            System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>          }
>        }
>        else
>        {
>          System.err.println("Item was not a map: " + item);
>        }
>      }
>
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>
>
>    // Third version, try to add the list as a value in a hash map.
>    // Doesn't work, array list is empty
>    System.out.println("----------------------- Third Test
> ---------------------------");
>    stream = new ByteArrayInputStream(xml.getBytes());
>    digester = DigesterLoader.createDigester(new InputSource(new
> ByteArrayInputStream(test3.getBytes())));
>    digester.setValidating(false);
>
>    HashMap testMap = new HashMap();
>    digester.push(testMap);
>
>    try
>    {
>     digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object key : testMap.keySet())
>      {
>        System.out.println("Map key: " + key);
>        ArrayList results = (ArrayList)testMap.get(key);
>
>        for (Object item : results)
>        {
>          if (item instanceof Map)
>          {
>            System.out.println("    Item:");
>            for(Object tag : ((Map)item).keySet())
>            {
>              System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>            }
>          }
>          else
>          {
>            System.err.println("Item was not a map: " + item);
>          }
>        }
>      }
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>
>    // Fourth version, try to add the list as a value in a hash map. Create
> the hash map in the rule
>    // Still doesn't work, array list is empty.
>    System.out.println("----------------------- Fourth Test
> ---------------------------");
>    stream = new ByteArrayInputStream(xml.getBytes());
>    digester = DigesterLoader.createDigester(new InputSource(new
> ByteArrayInputStream(test4.getBytes())));
>    digester.setValidating(false);
>
>    try
>    {
>      testMap = (HashMap)digester.parse(stream);
>
>      System.out.println("Results:");
>
>      for (Object key : testMap.keySet())
>      {
>        System.out.println("Map key: " + key);
>        ArrayList results = (ArrayList)testMap.get(key);
>
>        for (Object item : results)
>        {
>          if (item instanceof Map)
>          {
>            System.out.println("    Item:");
>            for(Object tag : ((Map)item).keySet())
>            {
>              System.out.println("      " + tag + ": " +
> ((Map)item).get(tag));
>            }
>          }
>          else
>          {
>            System.err.println("Item was not a map: " + item);
>          }
>        }
>      }
>    }
>    catch (IOException e)
>    {
>      e.printStackTrace();
>    }
>    catch (SAXException e)
>    {
>      e.printStackTrace();
>    }
>  }
> }
>

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


RE: [digester] Trouble adding a list to a hash map

Posted by Philip A Grim II <pg...@data-tactics.com>.
Apologies...wasn't thinking straight.

Here's the code.

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class DigestTester
{
  private static String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                              "<Envelope>" +
                              "  <Person>" +
                              "    <Locations>" +
                              "      <Location>" +
                              "
<Id>3eca4cd1-a07a-4013-b4a3-1d6a6530f7e3</Id>" +
                              "        <DateAsOf>201007132112</DateAsOf>" +
                              "
<DateLastModified>20100803203509203</DateLastModified>" +
                              "        <Name>Most Recent Location</Name>" +
                              "        <WKT>POINT (69.568583399873617
33.86775960347174 0)</WKT>" +
                              "      </Location>" +
                              "      <Location>" +
                              "
<Id>3e2462d1-a0c7-4013-4523-1345a3b8f7e3</Id>" +
                              "        <DateAsOf>201007100814</DateAsOf>" +
                              "
<DateLastModified>20100803203509203</DateLastModified>" +
                              "        <Name>Previous Location</Name>" +
                              "        <WKT>POINT (66.53455434533617
32.863453455537174 0)</WKT>" +
                              "      </Location>" +
                              "    </Locations>" +
                              "  </Person>" +
                              "</Envelope>";


  private static String test2 = "<?xml version=\"1.0\"?>" +
                                   "<digester-rules>" +
                                   "<pattern value=\"Envelope/Person\">" +
                                   "<object-create-rule
pattern=\"Locations\" classname=\"java.util.ArrayList\"/>" +
                                   "<object-create-rule
pattern=\"Locations/Location\" classname=\"java.util.HashMap\"/>" +
                                   "<call-method-rule
pattern=\"Locations/Location/Id\" targetoffset=\"0\" methodname=\"put\"
paramcount=\"2\"" +
                                   "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                   "<object-param-rule
pattern=\"Locations/Location/Id\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"id\"/>" +
                                   "<call-param-rule
pattern=\"Locations/Location/Id\" paramnumber=\"1\"/>" +
                                   "<call-method-rule
pattern=\"Locations/Location/DateAsOf\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                   "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                   "<object-param-rule
pattern=\"Locations/Location/DateAsOf\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"date_as_of\"/>" +
                                   "<call-param-rule
pattern=\"Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
                                   "<call-method-rule
pattern=\"Locations/Location/DateLastModified\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                   "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                   "<object-param-rule
pattern=\"Locations/Location/DateLastModified\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"date_last_modified\"/>" +
                                   "<call-param-rule
pattern=\"Locations/Location/DateLastModified\" paramnumber=\"1\"/>" +
                                   "<call-method-rule
pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
paramcount=\"2\"" +
                                   "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                   "<object-param-rule
pattern=\"Locations/Location/Name\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"name\"/>" +
                                   "<call-param-rule
pattern=\"Locations/Location/Name\" paramnumber=\"1\"/>" +
                                   "<call-method-rule
pattern=\"Locations/Location/WKT\" targetoffset=\"0\" methodname=\"put\"
paramcount=\"2\"" +
                                   "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                   "<object-param-rule
pattern=\"Locations/Location/WKT\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"wkt\"/>" +
                                   "<call-param-rule
pattern=\"Locations/Location/WKT\" paramnumber=\"1\"/>" +
                                   "<set-next-rule
pattern=\"Locations/Location\" methodname=\"add\"/>" +
                                   "</pattern>" + 
                                   "</digester-rules>";


  private static String test3 = "<?xml version=\"1.0\"?>" +
                                    "<digester-rules>" +
                                    "<pattern value=\"Envelope/Person\">" +
                                    "<object-create-rule
pattern=\"Locations\" classname=\"java.util.ArrayList\"/>" +
                                    "<object-create-rule
pattern=\"Locations/Location\" classname=\"java.util.HashMap\"/>" +
                                    "<call-method-rule
pattern=\"Locations/Location/Id\" targetoffset=\"0\" methodname=\"put\"
paramcount=\"2\"" +
                                    "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                    "<object-param-rule
pattern=\"Locations/Location/Id\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"id\"/>" +
                                    "<call-param-rule
pattern=\"Locations/Location/Id\" paramnumber=\"1\"/>" +
                                    "<call-method-rule
pattern=\"Locations/Location/DateAsOf\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                    "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                    "<object-param-rule
pattern=\"Locations/Location/DateAsOf\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"date_as_of\"/>" +
                                    "<call-param-rule
pattern=\"Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
                                    "<call-method-rule
pattern=\"Locations/Location/DateLastModified\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                    "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                    "<object-param-rule
pattern=\"Locations/Location/DateLastModified\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"date_last_modified\"/>" +
                                    "<call-param-rule
pattern=\"Locations/Location/DateLastModified\" paramnumber=\"1\"/>" +
                                    "<call-method-rule
pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
paramcount=\"2\"" +
                                    "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                    "<call-method-rule
pattern=\"Locations/Location/Name\" targetoffset=\"0\" methodname=\"put\"
paramcount=\"2\"" +
                                    "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                    "<object-param-rule
pattern=\"Locations/Location/Name\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"name\"/>" +
                                    "<call-param-rule
pattern=\"Locations/Location/Name\" paramnumber=\"1\"/>" +
                                    "<call-method-rule
pattern=\"Locations/Location/WKT\" targetoffset=\"0\" methodname=\"put\"
paramcount=\"2\"" +
                                    "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                    "<object-param-rule
pattern=\"Locations/Location/WKT\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"wkt\"/>" +
                                    "<call-param-rule
pattern=\"Locations/Location/WKT\" paramnumber=\"1\"/>" +
                                    "<set-next-rule
pattern=\"Locations/Location\" methodname=\"add\"/>" +
                                    "<call-method-rule pattern=\"Locations\"
targetoffset=\"1\" methodname=\"put\" paramcount=\"2\"" +
                                    "
paramtypes=\"java.lang.String,java.util.ArrayList\"/>" +
                                    "<object-param-rule
pattern=\"Locations\" paramnumber=\"0\" type=\"java.lang.String\"
value=\"locations\"/>" +
                                    "<object-param-rule
pattern=\"Locations\" paramnumber=\"1\" type=\"java.util.ArrayList\"
fromstack=\"true\"/>" +
                                    "</pattern>" + 
                                    "</digester-rules>";
  
  private static String test4 = "<?xml version=\"1.0\"?>" +
                                "<digester-rules>" +
                                "<pattern value=\"Envelope\">" +
                                "<object-create-rule pattern=\"Person\"
classname=\"java.util.HashMap\"/>" +
                                "<object-create-rule
pattern=\"Person/Locations\" classname=\"java.util.ArrayList\"/>" +
                                "<object-create-rule
pattern=\"Person/Locations/Location\" classname=\"java.util.HashMap\"/>" +
                                "<call-method-rule
pattern=\"Person/Locations/Location/Id\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                "<object-param-rule
pattern=\"Person/Locations/Location/Id\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"id\"/>" +
                                "<call-param-rule
pattern=\"Person/Locations/Location/Id\" paramnumber=\"1\"/>" +
                                "<call-method-rule
pattern=\"Person/Locations/Location/DateAsOf\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                "<object-param-rule
pattern=\"Person/Locations/Location/DateAsOf\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"date_as_of\"/>" +
                                "<call-param-rule
pattern=\"Person/Locations/Location/DateAsOf\" paramnumber=\"1\"/>" +
                                "<call-method-rule
pattern=\"Person/Locations/Location/DateLastModified\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                "<object-param-rule
pattern=\"Person/Locations/Location/DateLastModified\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"date_last_modified\"/>" +
                                "<call-param-rule
pattern=\"Person/Locations/Location/DateLastModified\" paramnumber=\"1\"/>"
+
                                "<call-method-rule
pattern=\"Person/Locations/Location/Name\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                "<call-method-rule
pattern=\"Person/Locations/Location/Name\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                "<object-param-rule
pattern=\"Person/Locations/Location/Name\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"name\"/>" +
                                "<call-param-rule
pattern=\"Person/Locations/Location/Name\" paramnumber=\"1\"/>" +
                                "<call-method-rule
pattern=\"Person/Locations/Location/WKT\" targetoffset=\"0\"
methodname=\"put\" paramcount=\"2\"" +
                                "
paramtypes=\"java.lang.Object,java.lang.Object\"/>" +
                                "<object-param-rule
pattern=\"Person/Locations/Location/WKT\" paramnumber=\"0\"
type=\"java.lang.String\" value=\"wkt\"/>" +
                                "<call-param-rule
pattern=\"Person/Locations/Location/WKT\" paramnumber=\"1\"/>" +
                                "<set-next-rule
pattern=\"Person/Locations/Location\" methodname=\"add\"/>" +
                                "<call-method-rule
pattern=\"Person/Locations\" targetoffset=\"1\" methodname=\"put\"
paramcount=\"2\"" +
                                "
paramtypes=\"java.lang.String,java.util.ArrayList\"/>" +
                                "<object-param-rule
pattern=\"Person/Locations\" paramnumber=\"0\" type=\"java.lang.String\"
value=\"locations\"/>" +
                                "<object-param-rule
pattern=\"Person/Locations\" paramnumber=\"1\" type=\"java.util.ArrayList\"
fromstack=\"true\"/>" +
                                "</pattern>" + 
                                "</digester-rules>";
  
  
  @SuppressWarnings("unchecked")
  public static void main(String[] args)
  {
    // First version, just make a list that contains a hash map.
    // This works, and values show up.
    System.out.println("----------------------- First Test
---------------------------");
    ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes());
    Digester digester = new Digester();
    digester.setValidating(false);
    
    digester.addObjectCreate("Envelope/Person/Locations",
"java.util.ArrayList");
    digester.addObjectCreate("Envelope/Person/Locations/Location",
"java.util.HashMap");
    
    digester.addCallMethod("Envelope/Person/Locations/Location/Id", "put",
2, new String[] { "java.lang.String", "java.lang.Object" });
    digester.addObjectParam("Envelope/Person/Locations/Location/Id", 0,
"id");
    digester.addCallParam("Envelope/Person/Locations/Location/Id", 1);
    
    digester.addCallMethod("Envelope/Person/Locations/Location/DateAsOf",
"put", 2, new String[] { "java.lang.String", "java.lang.Object" });
    digester.addObjectParam("Envelope/Person/Locations/Location/DateAsOf",
0, "date_as_of");
    digester.addCallParam("Envelope/Person/Locations/Location/DateAsOf", 1);
    
 
digester.addCallMethod("Envelope/Person/Locations/Location/DateLastModified"
, "put", 2, new String[] { "java.lang.String", "java.lang.Object" });
 
digester.addObjectParam("Envelope/Person/Locations/Location/DateLastModified
", 0, "date_last_modified");
 
digester.addCallParam("Envelope/Person/Locations/Location/DateLastModified",
1);
    
    digester.addCallMethod("Envelope/Person/Locations/Location/Name", "put",
2, new String[] { "java.lang.String", "java.lang.Object" });
    digester.addObjectParam("Envelope/Person/Locations/Location/Name", 0,
"name");
    digester.addCallParam("Envelope/Person/Locations/Location/Name", 1);
    
    digester.addCallMethod("Envelope/Person/Locations/Location/WKT", "put",
2, new String[] { "java.lang.String", "java.lang.Object" });
    digester.addObjectParam("Envelope/Person/Locations/Location/WKT", 0,
"wkt");
    digester.addCallParam("Envelope/Person/Locations/Location/WKT", 1);
    
    digester.addSetNext("Envelope/Person/Locations/Location", "add");
    
    try
    {
      ArrayList results = (ArrayList)digester.parse(stream);
      
      System.out.println("Results:");

      for (Object item : results)
      {
        if (item instanceof Map)
        {
          System.out.println("    Item:");
          for(Object tag : ((Map)item).keySet())
          {
            System.out.println("      " + tag + ": " +
((Map)item).get(tag));
          }
        }
        else
        {
          System.err.println("Item was not a map: " + item); 
        }
      }

    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    catch (SAXException e)
    {
      e.printStackTrace(); 
    }
    
    // Second version, just make a list that contains a hash map, using
xmlrules.
    // This works, and values show up.
    System.out.println("----------------------- Second Test
---------------------------");
    stream = new ByteArrayInputStream(xml.getBytes());
    digester = DigesterLoader.createDigester(new InputSource(new
ByteArrayInputStream(test2.getBytes())));
    digester.setValidating(false);
    try
    {
      ArrayList results = (ArrayList)digester.parse(stream);
      
      System.out.println("Results:");

      for (Object item : results)
      {
        if (item instanceof Map)
        {
          System.out.println("    Item:");
          for(Object tag : ((Map)item).keySet())
          {
            System.out.println("      " + tag + ": " +
((Map)item).get(tag));
          }
        }
        else
        {
          System.err.println("Item was not a map: " + item); 
        }
      }

    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    catch (SAXException e)
    {
      e.printStackTrace(); 
    }
  
  
    // Third version, try to add the list as a value in a hash map.
    // Doesn't work, array list is empty
    System.out.println("----------------------- Third Test
---------------------------");
    stream = new ByteArrayInputStream(xml.getBytes());
    digester = DigesterLoader.createDigester(new InputSource(new
ByteArrayInputStream(test3.getBytes())));
    digester.setValidating(false);
    
    HashMap testMap = new HashMap();
    digester.push(testMap);

    try
    {
     digester.parse(stream);

      System.out.println("Results:");

      for (Object key : testMap.keySet())
      {
        System.out.println("Map key: " + key);
        ArrayList results = (ArrayList)testMap.get(key);

        for (Object item : results)
        {
          if (item instanceof Map)
          {
            System.out.println("    Item:");
            for(Object tag : ((Map)item).keySet())
            {
              System.out.println("      " + tag + ": " +
((Map)item).get(tag));
            }
          }
          else
          {
            System.err.println("Item was not a map: " + item); 
          }
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    catch (SAXException e)
    {
      e.printStackTrace(); 
    }
    
    // Fourth version, try to add the list as a value in a hash map. Create
the hash map in the rule
    // Still doesn't work, array list is empty.
    System.out.println("----------------------- Fourth Test
---------------------------");
    stream = new ByteArrayInputStream(xml.getBytes());
    digester = DigesterLoader.createDigester(new InputSource(new
ByteArrayInputStream(test4.getBytes())));
    digester.setValidating(false);
    
    try
    {
      testMap = (HashMap)digester.parse(stream);

      System.out.println("Results:");

      for (Object key : testMap.keySet())
      {
        System.out.println("Map key: " + key);
        ArrayList results = (ArrayList)testMap.get(key);

        for (Object item : results)
        {
          if (item instanceof Map)
          {
            System.out.println("    Item:");
            for(Object tag : ((Map)item).keySet())
            {
              System.out.println("      " + tag + ": " +
((Map)item).get(tag));
            }
          }
          else
          {
            System.err.println("Item was not a map: " + item); 
          }
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    catch (SAXException e)
    {
      e.printStackTrace(); 
    }
  }
}


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


Re: [digester] Trouble adding a list to a hash map

Posted by Rahul Akolkar <ra...@gmail.com>.
On Fri, Oct 1, 2010 at 3:12 PM, Philip A Grim II <pg...@data-tactics.com> wrote:
>
> I'm having difficulty with the Digester when trying to add a list to a hash map.
>
> The following is a portion of the XML I'm digesting:
>
>
>
> <?xml version=\"1.0\" encoding=\"utf-8\"?>
>
> <Envelope>
>
>   <Person>
>
>     <Locations>
>
>       <Location>
>
>         <Id>3eca4cd1-a07a-4013-b4a3-1d6a6530f7e3</Id>
>
>         <DateAsOf>201007132112</DateAsOf>
>
>         <DateLastModified>20100803203509203</DateLastModified>
>
>         <Name>Most Recent Location</Name>
>
>         <WKT>POINT (69.568583399873617 33.86775960347174 0)</WKT>
>
>       </Location>
>
>       <Location>
>
>         <Id>3e2462d1-a0c7-4013-4523-1345a3b8f7e3</Id>
>
>         <DateAsOf>201007100814</DateAsOf>
>
>         <DateLastModified>20100803203509203</DateLastModified>
>
>         <Name>Previous Location</Name>
>
>         <WKT>POINT (66.53455434533617 32.863453455537174 0)</WKT>
>
>       </Location>
>
>     </Locations>
>
>   </Person>
>
> </Envelope>
>
>
>
> The top level object is a HashMap that contains properties of the Person tag.  Simple properties work fine, but nested properties such as Locations are what are giving me trouble.  I am trying to create an ArrayList of the Location tags which contains a HashMap of the properties nested inside each Location tag, and that part works, but when I try to add that ArrayList to the HashMap of person properties, I get an empty list.
>
>
>
> Please note that I have no control over the format of the XML itself...it is created by a third-party application, and I have to read what's there.
>
>
>
> Attached is a simple code example that shows what I've tried to do.  Either I'm doing it wrong or something isn't happening the way it should in the Digester.  I'd appreciate any help you could offer.
>
<snip/>

Attachment did not come through on the list. Best to inline the
smallest piece of code that fully captures the issue.

-Rahul


>
>
> Thanks,
>
> Phil
>
>
>
>
>
>
>
>
>
> Philip A Grim II
> Chief Engineer
> Data Tactics Corporation
> 7901 Jones Branch Dr.
> Suite 240
> McLean, VA  22102
>
> Cell: (717) 880-1714
>
>
>
> The information contained in this message may be privileged and/or confidential and protected from disclosure.  If the reader of this message is not the intended recipient or an employee or agent responsible for delivering this message to the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited.  If you have received this communication in error, please notify the sender immediately by replying to this message and deleting the material from any computer.
>

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