You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-user@axis.apache.org by Kevin Rogers <kr...@pdi.com> on 2005/10/14 20:31:35 UTC

Question about Axis xsd__ types

Hello,

I'm having some difficulties dealing with the Axis defined xsd__ types 
used for De/Serialization from SOAP. Basically, I had a service 
constructed which only used strings (well, actually char* as that's what 
Axis uses) for the parameters to the service calls, and everything 
worked great. I built an API around the Axis-generated that accepted 
char* as parameters and then passed those to the corresponding Axis call 
that accepted xsd__string's as it's parameters.

I know that xsd__string is typedef'd to 'char', so this was not a 
problem and worked great.

Originally, when I was only passing single strings my WSDL definition 
looked like this:

<xsd:element name="getLevels">
         <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="ProdCode" type="xsd:string"/>
                <xsd:element name="Type" type="xsd:string"/>
                ...

...the function generated from this WSDL has for it's parameters 
xsd__string, which I was successfully calling by doing something like this:

public myWrapper(char* aProdCode, char* aType)
{
    <.... code to get the ServicePortType...>

    theService->getLevels(aProdCode, aType);
}


However, I now want to change the API to accept arrays of strings 
(char*) and boolean values. Here is what my WSDL now looks like:

<xsd:element name="getLevels">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="ProdCode" type="xsd:string" minOccurs="1" 
maxOccurs="1"/>
            <xsd:element name="LevelNamePattern" type="xsd:string" 
minOccurs="0" maxOccurs="1"/>
            <xsd:element name="LevelType" type="xsd:string" 
minOccurs="0" maxOccurs="1"/>
            <xsd:element name="LevelIsIP" type="xsd:boolean" 
minOccurs="0" maxOccurs="1"/>
            <xsd:element name="Artist" type="xsd:string" minOccurs="0" 
maxOccurs="unbounded"/>
            ....


...the function generated from this WSDL now has for it's parameters 
xsd__string, xsd__boolean and xsd__string_Array values.

I know that xsd__string_Array is typedef'd to an array of xsd__string, 
which would mean an array of 'char', correct? I also see from the code 
that xsd__boolean is typedef'd to an enum containing true and false 
values. My wrapper API call now looks like this, accepting boolean and 
char*[] values:

public myWrapper(char* aProdCode, char* aLevelNamePattern", char* 
aLevelType, bool aLevelIsIP, char* aArtist[])
{
    <.... code to get the ServicePortType...>

    theService->getLevels(aProdCode, aLevelName Pattern, aLevelType, 
aLevelIsIP, aArtist);
}


However, the compiler complains with the above code (I've eliminated 
quite a few parameters in the above code for clarity):

LevelServiceAPI.cpp: In function `tLevel_Array
   getLevels(char*, char*, char*, bool, char*, char*, char**, char**, 
char**,
   char**, char**, char**, char*, char**, char**, char*, char**, bool, 
char**,
   char*, char*)':
LevelServiceAPI.cpp:106: no matching function for call to
   `LevelsServicePortType::getLevels(char*&, char*&, char*&, bool, char*&,
   char*&, char**&, char**&, char**&, char**&, char**&, char**&, char*&,
   char**&, char**&, char*&, char**&, bool, char**&, char*&, char*&)'
LevelsServicePortType.hpp:28: candidates are: tLevel_Array
   LevelsServicePortType::getLevels(char*, char*, char*, 
axiscpp::xsd__boolean,
   char*, char*, axiscpp::xsd__string_Array, axiscpp::xsd__string_Array,
   axiscpp::xsd__string_Array, axiscpp::xsd__string_Array,
   axiscpp::xsd__string_Array, axiscpp::xsd__string_Array, char*,
   axiscpp::xsd__string_Array, axiscpp::xsd__string_Array, char*,
   axiscpp::xsd__string_Array, axiscpp::xsd__boolean,
   axiscpp::xsd__string_Array, char*, char*)


All of the parameters defined in the ServicePortType function with type 
of xsd__String_Array or xsd_boolean are mapped to char** and boolean 
values accordingly. One strange thing that I did notice was that the 
compiler changed the references of xsd__string to char* when outputting 
the above message, but did not do so for xsd__string_Array or 
xsd__boolean. (What I mean by that is that the definition of the 
function in the ServicePortType class has xsd__string, xsd__string_Array 
and xsd__boolean as it's parameters, but the compiler seems to only 
decode the references to xsd__string to it's corresponding char* value).

Can anyone shed some light on this?


thanks!
~kevin

-- 
Kevin Rogers
PDI / Dreamworks
ext.29163 | 650.562.9163
krogers@pdi.com


Re: Question about Axis xsd__ types

Posted by Kevin Rogers <kr...@pdi.com>.
Adrian Dick wrote:

>Hi,
>
>I think you have mis-understood the API for Arrays here.
>
>Because we need to handle nil (or NULL) elements within arrays, we can't
>simply use a NULL terminated array.  Therefore we have a small class to
>hold the array, of the following structure (using xsd__string example):
>  class xsd__string_Array
>  {
>    public:
>      xsd__string * m_Array;
>      int m_Size; // Size of array (inc. NULL or empty elements)
>  };
>
>Which you would use something like:
>  xsd__string_Array arrayInput;
>  arrayInput.m_Array = new xsd__string[2];
>  arrayInput.m_Size = 2;
>  webServiceStub->methodWithArrayInput(arrayInput);
>  
>



Thank you for your help, greatly appreciated. =)

I am having some issues with the serialization of these arrays , 
however. I'm handling the xsd__string_Array objects just as described:

---

// already defined:
std::vector<std::string> aVector;
xsd__string_Array aXsdArray;

//then do something like:

aXsdArray.m_Size = aVector.size();

char* theArr[aXsdArray.m_Size + 1]; // + 1 for the NULL terminator (is 
this needed?)

int i = 0;

for (std::vector<std::string>::iterator p = aVector.begin(); 
p!=aVector.end(); p++)
{
std::string theStr = *p;

theArr[i] = const_cast<char*>(theStr.c_str());
i++;
}

theArr[i] = NULL;

aXsdArray.m_Array = theArr;

---

I've stepped through this with gdb and it seems to be doing just what I 
would like (aside from the NULL termination, which I don't know whether 
or not is needed).

 From my previous email, these xsd__string_Array objects are elements of 
a complex type:

<xsd:element name="getLevels">
        <xsd:complexType>
          <xsd:sequence>
            ...some other elements...
            <xsd:element name="Artist" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>


When I call the service, the output from TCPMon is below. All of the 
xsd__string_Array elements seem to have one incorrect entry (I was 
anticipating multiple entries for each array element containing the 
distinct values - is that correct?).

thanks,
~kevin


----------------------
SOAP request:
----------------------

POST /nile/services/LevelsService HTTP/1.1
Host: denial:2000
Content-Type: text/xml; charset=UTF-8
SOAPAction: ""
Content-Length: 1296

<?xml version='1.0' encoding='utf-8' ?>
<SOAP-ENV:Envelope 
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:getLevels xmlns:ns1="http://www.dreamworks.com/nile/schema/">
<ns1:ProdCode>MAD</ns1:ProdCode>
<ns1:LevelNamePattern>some level name pattern</ns1:LevelNamePattern>
<ns1:LevelType>FX</ns1:LevelType>
<ns1:LevelIsIP>true</ns1:LevelIsIP>
<ns1:Note>Some note</ns1:Note>
<ns1:NotePattern>some note pattern</ns1:NotePattern>
<ns1:Artist>p���</ns1:Artist>
<ns1:TaskName>p���</ns1:TaskName>
<ns1:CompletedDate>p���</ns1:CompletedDate>
<ns1:Attempt>p���</ns1:Attempt>
<ns1:LevelReuse>p���</ns1:LevelReuse>
<ns1:SequenceName>p���</ns1:SequenceName>
<ns1:SequenceNamePattern>some seqname pattern</ns1:SequenceNamePattern>
<ns1:SequenceStatus>p���</ns1:SequenceStatus>
<ns1:ShotName>p���</ns1:ShotName>
<ns1:ShotNamePattern>some shotname pattern</ns1:ShotNamePattern>
<ns1:ShotStatus>p���</ns1:ShotStatus>
<ns1:ShotIsOnHold>false</ns1:ShotIsOnHold>
<ns1:ShotPriority>p���</ns1:ShotPriority>
<ns1:ShotPriorityPattern>some shotprior pattern</ns1:ShotPriorityPattern>
<ns1:UserLogin>krogers</ns1:UserLogin>
</ns1:getLevels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


----------------------
SOAP response:
----------------------

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Wed, 19 Oct 2005 20:57:42 GMT
Server: Apache-Coyote/1.1
Connection: close

21e
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server.userException</faultcode><faultstring>java.io.UTFDataFormatException: 
Invalid byte 1 of 1-byte UTF-8 
sequence.</faultstring><detail><ns1:hostname 
xmlns:ns1="http://xml.apache.org/axis/">denial.pdi.com</ns1:hostname></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope> 

0

-- 
Kevin Rogers
PDI / Dreamworks
ext.29163 | 650.562.9163
krogers@pdi.com


Re: Question about Axis xsd__ types

Posted by Adrian Dick <ad...@uk.ibm.com>.
Hi,

I think you have mis-understood the API for Arrays here.

Because we need to handle nil (or NULL) elements within arrays, we can't
simply use a NULL terminated array.  Therefore we have a small class to
hold the array, of the following structure (using xsd__string example):
  class xsd__string_Array
  {
    public:
      xsd__string * m_Array;
      int m_Size; // Size of array (inc. NULL or empty elements)
  };

Which you would use something like:
  xsd__string_Array arrayInput;
  arrayInput.m_Array = new xsd__string[2];
  arrayInput.m_Size = 2;
  webServiceStub->methodWithArrayInput(arrayInput);

I hope this is of help.


Regards,
Adrian
_______________________________________
Adrian Dick (adrian.dick@uk.ibm.com)

Kevin Rogers <kr...@pdi.com> wrote on 14/10/2005 19:31:35:

>
> Hello,
>
> I'm having some difficulties dealing with the Axis defined xsd__ types
> used for De/Serialization from SOAP. Basically, I had a service
> constructed which only used strings (well, actually char* as that's what
> Axis uses) for the parameters to the service calls, and everything
> worked great. I built an API around the Axis-generated that accepted
> char* as parameters and then passed those to the corresponding Axis call
> that accepted xsd__string's as it's parameters.
>
> I know that xsd__string is typedef'd to 'char', so this was not a
> problem and worked great.
>
> Originally, when I was only passing single strings my WSDL definition
> looked like this:
>
> <xsd:element name="getLevels">
>          <xsd:complexType>
>             <xsd:sequence>
>                 <xsd:element name="ProdCode" type="xsd:string"/>
>                 <xsd:element name="Type" type="xsd:string"/>
>                 ...
>
> ...the function generated from this WSDL has for it's parameters
> xsd__string, which I was successfully calling by doing something like
this:
>
> public myWrapper(char* aProdCode, char* aType)
> {
>     <.... code to get the ServicePortType...>
>
>     theService->getLevels(aProdCode, aType);
> }
>
>
> However, I now want to change the API to accept arrays of strings
> (char*) and boolean values. Here is what my WSDL now looks like:
>
> <xsd:element name="getLevels">
>         <xsd:complexType>
>           <xsd:sequence>
>             <xsd:element name="ProdCode" type="xsd:string" minOccurs="1"
> maxOccurs="1"/>
>             <xsd:element name="LevelNamePattern" type="xsd:string"
> minOccurs="0" maxOccurs="1"/>
>             <xsd:element name="LevelType" type="xsd:string"
> minOccurs="0" maxOccurs="1"/>
>             <xsd:element name="LevelIsIP" type="xsd:boolean"
> minOccurs="0" maxOccurs="1"/>
>             <xsd:element name="Artist" type="xsd:string" minOccurs="0"
> maxOccurs="unbounded"/>
>             ....
>
>
> ...the function generated from this WSDL now has for it's parameters
> xsd__string, xsd__boolean and xsd__string_Array values.
>
> I know that xsd__string_Array is typedef'd to an array of xsd__string,
> which would mean an array of 'char', correct? I also see from the code
> that xsd__boolean is typedef'd to an enum containing true and false
> values. My wrapper API call now looks like this, accepting boolean and
> char*[] values:
>
> public myWrapper(char* aProdCode, char* aLevelNamePattern", char*
> aLevelType, bool aLevelIsIP, char* aArtist[])
> {
>     <.... code to get the ServicePortType...>
>
>     theService->getLevels(aProdCode, aLevelName Pattern, aLevelType,
> aLevelIsIP, aArtist);
> }
>
>
> However, the compiler complains with the above code (I've eliminated
> quite a few parameters in the above code for clarity):
>
> LevelServiceAPI.cpp: In function `tLevel_Array
>    getLevels(char*, char*, char*, bool, char*, char*, char**, char**,
> char**,
>    char**, char**, char**, char*, char**, char**, char*, char**, bool,
> char**,
>    char*, char*)':
> LevelServiceAPI.cpp:106: no matching function for call to
>    `LevelsServicePortType::getLevels(char*&, char*&, char*&, bool,
char*&,
>    char*&, char**&, char**&, char**&, char**&, char**&, char**&, char*&,
>    char**&, char**&, char*&, char**&, bool, char**&, char*&, char*&)'
> LevelsServicePortType.hpp:28: candidates are: tLevel_Array
>    LevelsServicePortType::getLevels(char*, char*, char*,
> axiscpp::xsd__boolean,
>    char*, char*, axiscpp::xsd__string_Array, axiscpp::xsd__string_Array,
>    axiscpp::xsd__string_Array, axiscpp::xsd__string_Array,
>    axiscpp::xsd__string_Array, axiscpp::xsd__string_Array, char*,
>    axiscpp::xsd__string_Array, axiscpp::xsd__string_Array, char*,
>    axiscpp::xsd__string_Array, axiscpp::xsd__boolean,
>    axiscpp::xsd__string_Array, char*, char*)
>
>
> All of the parameters defined in the ServicePortType function with type
> of xsd__String_Array or xsd_boolean are mapped to char** and boolean
> values accordingly. One strange thing that I did notice was that the
> compiler changed the references of xsd__string to char* when outputting
> the above message, but did not do so for xsd__string_Array or
> xsd__boolean. (What I mean by that is that the definition of the
> function in the ServicePortType class has xsd__string, xsd__string_Array
> and xsd__boolean as it's parameters, but the compiler seems to only
> decode the references to xsd__string to it's corresponding char* value).
>
> Can anyone shed some light on this?
>
>
> thanks!
> ~kevin
>
> --
> Kevin Rogers
> PDI / Dreamworks
> ext.29163 | 650.562.9163
> krogers@pdi.com
>