I finally achieved what I needed, but it was hard work !

I added a new function yaws_soap_lib:initModelOptions that allows me to pass in erlsom options, instead of faking them in yaws_soap_lib:initModel2; also a new function yaws_soap_srv:setupOptions that allows me to use the new initialisation in the server.  That allowed me to pass in a custom include_fun that applies the appropriate prefix for the namespaces I'm interested in.  I'd be happy to contribute the code back to yaws if a committer is interested.

Chandru's suggestion gave me the clues I needed, but I struggled with it a) because erlsoap is virtually unobtainable (sources seem to have vanished from sourceforge) and b) because yaws scans the wsdl file and automatically pulls in the xsd schemas, and doesn't seem to honour the include_files options in the config file.

Anyway, thanks for the assistance,

On Wed, Aug 4, 2010 at 5:33 AM, Chandru <chandrashekhar.mullaparthi@gmail.com> wrote:
Hi Tom,

On 3 August 2010 20:45, Tom Hay <tomhay99@googlemail.com> wrote:
(apologies if this post is duplicated)

I have a problem because yaws_soap_lib uses a single prefix even when the WSDL specifies multiple namespaces.  My WSDL definitions section contains these lines:


Ideally I would like the prefix to reflect the namespace, so I would get:

-record('ct:Document', {anyAttribs, 'FIToFICstmrCdtTrf'}).
-record('psr:Document', {anyAttribs, 'FIToFIPmtStsRpt'}).

Is there an easy way to achieve this?  Or a clean work-around?

I believe yaws_soap_lib uses erlsom to compile XSDs and WSDLs. When using erlsom, you can specify a config file to use during the compilation process.  Here is an example:

  <wsdl_file name="csRead.wsdl" prefix="csRead">

    <import_specs namespace="http://messaging.ei.tmobile.net/datatypes"
          prefix="ei" location="ei.messaging.datatypes.xsd"></import_specs>

    <import_specs namespace="http://excalibur.rbp.tmobile.net/datatypes/UK/csRead/csGtRtnOfr"
          prefix="csGtRtnOfr" location="net-tmobile-rbp-excalibur-datatypes-UK-csRead-csGtRtnOfr.xsd"></import_specs>


We then use this snippet of code to generate our header files.

compile_wsdl(Wsdl, Wsdl_erlsoap_config) ->
    Header_file_name = filename:basename(Wsdl, ".wsdl") ++ ".hrl",
    Model_header_file_name = filename:basename(Wsdl, ".wsdl") ++ "_model.hrl",
    Model = erlsoap_lib:initModelFile(Wsdl_erlsoap_config),
    ok = erlsoap_lib:write_hrl(Model, Header_file_name),
    {ok, Iod} = file:open(Model_header_file_name, [write]),
    io:format(Iod, "-define(~s_MODEL, ~p).~n", [filename:basename(Wsdl, ".wsdl"), Model]),

add_boiler_plate(Filename) ->
    io:format("Adding boiler plate to ~s...~n", [Filename]),
    Base_name = filename:basename(Filename),
    Base_name_without_dot = lists:map(fun($.) ->
                     (X) ->
                      end, Base_name),
    case file:read_file(Filename) of
    {ok, Bin} ->
        File_str = binary_to_list(Bin),
        case lists:prefix("-ifndef", File_str) of
        true ->
            io:format("Not adding boilerplate to ~s. Already exists~n",
        false ->
            X = string:to_upper(Base_name_without_dot),
            ok = file:write_file(
                        "-define(~s, \"~s\").~n~n"
                        "-vsn('$Id:"" $ ').~n"
                        "-vsn('$URL:"" $ ').~n" ,
                        [X, X, Base_name]),
    Err ->
        io:format("Error adding boilerplate to ~s. Reason: ~p~n",
              [Filename, Err])