Trouble with passing subtypes..

Help
Hari
2011-10-25
2013-04-15
  • Hari
    Hari
    2011-10-25

    Hi,

           I am quite new to Erlang and trying to call a SOAP webservice using yaws (which uses erlsom). I am able to call webservice methods which dont have complex types as arguments..
    For eg: If the method generated from parsing the wsdl is like,
    {type,'P:methodName1',sequence,,,undefined,undefined,1,1,1,undefined,undefined} , I can call them without any problems since the argument part is .

    But when the arguments have to be supplied or becomes mandatory I have big trouble in passing the sub types.

    For eg: If the model is like,
    {type,'P:methodName2',sequence, [{el,[{alt,param1,{'#PCDATA',char},,1,1,true,undefined}], 0,1,1},
    {el,[{alt,param2,{'#PCDATA',char},,1,1,true,undefined}], 0,1,2},
    {el,[{alt,param3,{'#PCDATA',char},,1,1,true,undefined}], 0,1,3},
    {el,[{alt,param4, {'#PCDATA',char},,1,1,true,undefined}],0,1,4},
    {el,[{alt,param5,'P:property',,1,1,true,undefined}],0,unbound,5}],
    ,undefined,undefined,6,1,1,undefined,undefined}

    then I can pass the normal arguments (having type as {'#PCDATA',char}) without any problems. I passed them as string and its working. But when it comes to the 'param5' which is of type 'P:property', I dont know how to pass it.

    I tried to pass it (param5) as a list of tuples, list of strings, etc. No success.
    For eg, one such error message was:
    4> ws_soap:ws_soap_call (Wsdl, "methodName2", ["PARAM_VALUE1", "PARAM_VALUE2", "PARAM_VALUE3", "PARAM_VALUE4", ]).
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    RecordType = "PARAM51"
    ** exception error: bad argument
         in function  atom_to_list/1
            called as atom_to_list("PARAM51")
         in call from erlsom_write:findAlternative/4
         in call from erlsom_write:processSubType/5
         in call from erlsom_write:processElementValues/7
         in call from erlsom_write:struct2xml/6
         in call from erlsom_write:processAlternativeValue/8
         in call from erlsom_write:processElementValues/7
         in call from erlsom_write:struct2xml/6

    Please let me know if more details or clarifications are required. I am stuck due to this. I tried digging into the code which is consuming a lot of time since I am new to Erlang.

    Please help.

    Thanks,
    Sreehari

     
  • Willem de Jong
    Willem de Jong
    2011-10-25

    Hi,

    If you have 'subtypes', you should use a record as the value, with nested records for the 'subtypes'. If the subtype can occur more than once (as seems to be the case in your example), it should be a list of records.

    In your example, it may look like this (roughly): {'P:methodName2', , "PARAM_VALUE1", "PARAM_VALUE2", "PARAM_VALUE3", "PARAM_VALUE4", [{'P:property', ,  "PARAM_VALUE51", "PARAM_VALUE52"}]}

    Or, in record notation: #'P:methodName2'{param1="PARAM_VALUE1", … param5=}

    Take a look at the Erlsom documentation, and try to use yaws_soap_lib:write_hrl(…) to create a set of record declarations.

    Regards,
    Willem

     
  • Hari
    Hari
    2011-10-26

    x Willem,

               thanks very much for your quick reply. I created a new record for the type 'P:property' as you mentioned.
    **
    -record ('P:property', {name, value}).
    the P:property is,

    <xs:complexType name="property">
        <xs:sequence>
          <xs:element name="name" type="tns:entityProperty" minOccurs="0"/>
          <xs:element name="value" type="xs:string" minOccurs="0"/>
        </xs:sequence>
      </xs:complexType> **

    tns:entityProperty is xs:simpleType, so I hope its ok. The record has to be created only for 'P:property' as I understand, please correct me if I am wrong.

    After that I called webservice again.

    ws_soap:ws_soap_call (Wsdl, "methodName2", ["VALUE1", "VALUE2", "VALUE3", "VALUE4", ]).

    But now, it is crashing at:

    ** exception error: no function clause matching
                        erlsom_write:processAnyAttributes("PVALUE1",,
                                                          [{ns,
                                                            "http://schemas.xmlsoap.org/soap/envelope/",
                                                            "soap"},
                                                           {ns,
                                                            "http://url/",
                                                            "P"},
                                                           {ns,
                                                            "http://www.w3.org/2001/XMLSchema",
                                                            "xsd"}],
                                                          {[{"P",
                                                             "http://url"},
                                                            {"soap",
                                                             "http://schemas.xmlsoap.org/soap/envelope/"}],
                                                           0})
         in function  erlsom_write:processAlternativeValue/8
         in call from erlsom_write:processElementValues/7
         in call from erlsom_write:struct2xml/6
         in call from erlsom_write:processAlternativeValue/8
         in call from erlsom_write:processElementValues/7
         in call from erlsom_write:struct2xml/6
         in call from erlsom_write:processAlternativeValue/8

    May be I didnt understand your reply completely. But can you look into this? I believe I am passing the function name and the rest of the parameters correctly. arent I? I used the write_hrl method, but it didnt give much information about the subtypes.

    Hari

     
  • Hari
    Hari
    2011-11-08

    hi Willem,

            sorry to bug you.. but can u help me? I tried different combinations with my Erlang and XML knowledge.

    Thanks,
    Hari

     
  • Hari
    Hari
    2011-11-08

    finally after a lot of trial and error I managed to succeed.

    in the call that Willem mentioned,

    willem
    In your example, it may look like this (roughly): {'P:methodName2', , "PARAM_VALUE1", "PARAM_VALUE2", "PARAM_VALUE3", "PARAM_VALUE4", [{'P:property', ,  "PARAM_VALUE51", "PARAM_VALUE52"}]}

                         there was some minor changes required for me to work.

    {"PARAM_VALUE1", "PARAM_VALUE2", "PARAM_VALUE3", "PARAM_VALUE4", [{'P:property', ,  "PARAM_NAME51", "PARAM_VALUE51"}, {'P:property', ,  "PARAM_NAME52", "PARAM_VALUE52"}, …]}

    I have to omit the method name as it was throwing some error and then it started to work (although with some error thrown by the web service) and finally I arrived in this.

    I still dont know how to use records for this context, but this is enough for me at the moment.

    Thanks Willem for your support. :)

    Hari