function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
fruserfruser 

Iterating through fields of returned objects to get name/value pairs

Hi,

    Is there way to iterate through the fields of Object returned through the QueryResult and get the name/value of the fields.

 Currently the only way I could see is to get to the fields is the get set methods  for that particular field. Which implies that I need to know what fields are there in the returned object, which is file if I am writing the query in the code and I know what fields will be returned. But if I am makinga tool to allow a user to specifiy the query and the tool generates an XML out of the returned objects then a generic method to loop through the fields will be very helpful. I think the previous API since every thing was loaded in a hash map, therefore it was much easier to do what I am trying to do.

Thanks

fruser

adamgadamg
Are you using the partner or enterprise API?  For the partner API, the following will create a vector of hashtables of the results (probably not too graceful, but it works):
 
 public Vector processQuery(SObject[] results) {
Vector v = new Vector();

org.apache.axis.message.MessageElement[] mElement = null;
if (results != null) {


// get keys
results[0].getType();
SObject res = results[0];
mElement = res.get_any();
for (int i=0;i<mElement.length;i++){
org.apache.axis.message.MessageElement xEl = mElement[i];
if (xEl != null) {
xEl.getName();
}
}

// get values
for (int i=0;i<results.length;i++) {
Hashtable _hash = new Hashtable();
mElement = results[i].get_any();
if (mElement != null)
{
if (results[i].getId()!=null) {
_hash.put("ID",results[i].getId());
}
for (int j=0;j<mElement.length;j++)
{
org.apache.axis.message.MessageElement xEl = mElement[j];
if (xEl == null)
{ ; }
else {
_hash.put(xEl.getName(),xEl.getValue());
}
}

}
v.add(_hash);
}

}

return v;

}
MaumanMauman
The code example in the previous reply is great except from what I can tell, there is no "get_any()" function within the SObject class.  Is there another way to extract the "MessageElement" objects from the SObject objects?
adamgadamg
I'm not sure I understand the question; there is a "get_any()" function on SObject, which returns and XML structure you can navigate using the Axis libraries.
MaumanMauman

Well, here is what I've got for SObject.java, and I don't see where the "get_any()" function is:

/**
 * SObject.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis WSDL2Java emitter.
 */

package com.sforce.soap.enterprise.sobject;

public abstract class SObject  implements java.io.Serializable {
    private java.lang.String[] fieldsToNull;
    private com.sforce.soap.enterprise.ID id;

    public SObject() {
    }

    public java.lang.String[] getFieldsToNull() {
        return fieldsToNull;
    }

    public void setFieldsToNull(java.lang.String[] fieldsToNull) {
        this.fieldsToNull = fieldsToNull;
    }

    public java.lang.String getFieldsToNull(int i) {
        return fieldsToNull[i];
    }

    public void setFieldsToNull(int i, java.lang.String value) {
        this.fieldsToNull[i] = value;
    }

    public com.sforce.soap.enterprise.ID getId() {
        return id;
    }

    public void setId(com.sforce.soap.enterprise.ID id) {
        this.id = id;
    }

    private java.lang.Object __equalsCalc = null;
    public synchronized boolean equals(java.lang.Object obj) {
        if (!(obj instanceof SObject)) return false;
        SObject other = (SObject) obj;
        if (obj == null) return false;
        if (this == obj) return true;
        if (__equalsCalc != null) {
            return (__equalsCalc == obj);
        }
        __equalsCalc = obj;
        boolean _equals;
        _equals = true &&
            ((this.fieldsToNull==null && other.getFieldsToNull()==null) ||
             (this.fieldsToNull!=null &&
              java.util.Arrays.equals(this.fieldsToNull, other.getFieldsToNull()))) &&
            ((this.id==null && other.getId()==null) ||
             (this.id!=null &&
              this.id.equals(other.getId())));
        __equalsCalc = null;
        return _equals;
    }

    private boolean __hashCodeCalc = false;
    public synchronized int hashCode() {
        if (__hashCodeCalc) {
            return 0;
        }
        __hashCodeCalc = true;
        int _hashCode = 1;
        if (getFieldsToNull() != null) {
            for (int i=0;
                 i<java.lang.reflect.Array.getLength(getFieldsToNull());
                 i++) {
                java.lang.Object obj = java.lang.reflect.Array.get(getFieldsToNull(), i);
                if (obj != null &&
                    !obj.getClass().isArray()) {
                    _hashCode += obj.hashCode();
                }
            }
        }
        if (getId() != null) {
            _hashCode += getId().hashCode();
        }
        __hashCodeCalc = false;
        return _hashCode;
    }

    // Type metadata
    private static org.apache.axis.description.TypeDesc typeDesc =
        new org.apache.axis.description.TypeDesc(SObject.class);

    static {
        typeDesc.setXmlType(new javax.xml.namespace.QName("urn:sobject.enterprise.soap.sforce.com", "sObject"));
        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("fieldsToNull");
        elemField.setXmlName(new javax.xml.namespace.QName("urn:sobject.enterprise.soap.sforce.com", "fieldsToNull"));
        elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        elemField.setMinOccurs(0);
        typeDesc.addFieldDesc(elemField);
        elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("id");
        elemField.setXmlName(new javax.xml.namespace.QName("urn:sobject.enterprise.soap.sforce.com", "Id"));
        elemField.setXmlType(new javax.xml.namespace.QName("urn:enterprise.soap.sforce.com", "ID"));
        elemField.setMinOccurs(0);
        typeDesc.addFieldDesc(elemField);
    }

    /**
     * Return type metadata object
     */
    public static org.apache.axis.description.TypeDesc getTypeDesc() {
        return typeDesc;
    }

    /**
     * Get Custom Serializer
     */
    public static org.apache.axis.encoding.Serializer getSerializer(
           java.lang.String mechType,
           java.lang.Class _javaType, 
           javax.xml.namespace.QName _xmlType) {
        return
          new  org.apache.axis.encoding.ser.BeanSerializer(
            _javaType, _xmlType, typeDesc);
    }

    /**
     * Get Custom Deserializer
     */
    public static org.apache.axis.encoding.Deserializer getDeserializer(
           java.lang.String mechType,
           java.lang.Class _javaType, 
           javax.xml.namespace.QName _xmlType) {
        return
          new  org.apache.axis.encoding.ser.BeanDeserializer(
            _javaType, _xmlType, typeDesc);
    }

}

adamgadamg
Ahh.  You want the partner API & WSDL (com.salesforce.partner.SObject, I think), not the enterprise API.  You can have both in the same project; just be sure to qualify the packages appropriately.
MaumanMauman

Why are the com.salesforce.partner.SObject and com.salesforce.enterprise.SObject so different? 

It is not cool that I can only do certain things using each package.  If one was a subset of the other that would be fine, but it appears to not be the case because when I build the com.salesforce.partner package using Axis, it doesn't build any of the object files (e.g. Account, Contact, Opportunity, etc.).

You probably don't have an answer.  I guess this is just a "feature request".

adamgadamg
Ok - there are a few different issues here.
 
The Partner and Enterprise APIs (and corresponding WSDLs), are two SEPERATE APIs.  While they have simularities, one is a loosely typed API, and the other is strongly typed.  Hence, for the Partner API, there are no "types" (objects) for the sforce entities such as lead, contact, etc, and instead only a single SObject type.
 
If you want to work with a hash of key/value pairs of a given object, there are two ways to do this.  The most "natural" (as they are both weakly typed) is to use the Partner API.  If you want to generate key/value pairs from the Enterprise API, I can provide sample code that does that, but would want to make sure there isn't a simpler solution, as it kind of defeats the purpose of Enterprise (strongly typed) API to begin with.
 
Make sense?
MaumanMauman

Yes.  That makes sense.  Thank you!

That being the case, I await the Partner API Samples!

adamgadamg

The sample posted above will generate key/values for an SObject using the partner API.  Let me know if you looking for something different.

Adam

megha naikmegha naik
Hi Adam,
I want to loop through all fields of any salesforce table using Enterprise API. Currently i am using reflection to cast return object from QueryResult to Object type and dynamically invoke getters for the fields(use DescribeSObjectResult to query fields). Wondering if you have cleaner solution than this.
Megha