axis-c-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "McCullough, Ryan" <rmccullo...@rightnow.com>
Subject trouble parsing response
Date Tue, 27 May 2008 22:07:53 GMT
We are having a problem parsing the return from the server (non axis).

 

Our wsdl has these definitions:

 

  <message name="exec">

    <part name="parameters" element="ons:exec" />

  </message>

  <message name="exec_rv">

    <part name="parameters" element="ons:exec_rv" />

  </message>

  <portType name="Soap">

    <operation name="exec">

      <input message="tns:exec" />

      <output message="tns:exec_rv" />

    </operation>

  </portType>

 

Ons is defined as xmlns:ons="urn:obj.api.rightnow.com"

 

The exec element is defined as:

    <xs:element name="exec">

        <xs:complexType>

            <xs:sequence>

                <xs:element name="transaction" type="transaction"
minOccurs="1" maxOccurs="unbounded" />

            </xs:sequence>

        </xs:complexType>

    </xs:element>

 

And the exec_rv:

    <xs:element name="exec_rv">

        <xs:complexType>

            <xs:sequence>

                <xs:element name="fatal_err_rv"   type="fatal_err_rv"
minOccurs="0" maxOccurs="1" />

                <xs:element name="trans_abort_rv" type="trans_abort_rv"
minOccurs="0" maxOccurs="1" />

                <xs:element name="transaction_rv" type="transaction_rv"
minOccurs="0" maxOccurs="unbounded" />

            </xs:sequence>

        </xs:complexType>

    </xs:element>

 

 

The 'transaction' type is a complexType with a 'choice' of elements. The
elements have a type which maps to a complex type and they all have a
minOccurs of 0. Here is an example:

 

<xs:complexType name="transaction">

    <xs:choice minOccurs="1" maxOccurs="unbounded">

       <xs:element name="account_login" type="login_data" minOccurs="0"
maxOccurs="unbounded" />

       <xs:element name="create_id" type="tbl_iv" minOccurs="0"
maxOccurs="unbounded" />

       <xs:element name="org_create" type="org" minOccurs="0"
maxOccurs="unbounded" />

    </xs:choice>

</xs:complexType>

 

The 'transaction_rv' type looks very similar to the transaction type.

 

'trans_abort_rv' is an extension to transaction_rv.

 

'fatal_err_rv' is a complexType with 'sequence' elements containing data
about the fatal error.

 

My Soap.cpp stub has an exec() function in it that takes 4 params:

exec(Transaction_Array* Value0, 

      AXIS_OUT_PARAM Fatal_err_rv* * OutValue0, 

      AXIS_OUT_PARAM Trans_abort_rv* * OutValue1, 

      AXIS_OUT_PARAM Transaction_rv_Array ** OutValue2)

 

The response from the server looks something like this:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"

               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

               xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<soap:Header>

<ResponseHeader xmlns="urn:obj.api.rightnow.com">

<Version>8.11.0.4</Version>

</ResponseHeader>

</soap:Header>

<soap:Body>

<exec_rv xmlns="urn:obj.api.rightnow.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<transaction_rv errlog_cnt="0">

<account_login_rv><acct_id>*****</acct_id>

<session_id>**********</session_id>

</account_login_rv>

</transaction_rv>

</exec_rv>

</soap:Body>

</soap:Envelope>

 

The problem is that in the exec() function, it tries to getCmplxObject() for
fatal_err_rv, then getCmplxObject() for trans_abort_rv, then it tries to
getCmplxArray() for transaction_rv but by now the current node is up to
account_login_rv. Here is the c++ code from Soap::exec()

 

if (AXIS_SUCCESS == m_pCall->sendAndReceive())

{

  if(AXIS_SUCCESS == m_pCall->checkMessage("exec_rv",
"urn:obj.api.rightnow.com"))

  {

    *OutValue0 = (Fatal_err_rv*)m_pCall->getCmplxObject((void*)
Axis_DeSerialize_Fatal_err_rv, (void*) Axis_Create_Fatal_err_rv, (void*)
Axis_Delete_Fatal_err_rv,"fatal_err_rv", 0);

 

    *OutValue1 = (Trans_abort_rv*)m_pCall->getCmplxObject((void*)
Axis_DeSerialize_Trans_abort_rv, (void*) Axis_Create_Trans_abort_rv, (void*)
Axis_Delete_Trans_abort_rv,"trans_abort_rv", 0);

 

    if (OutValue2 != NULL)

    {

      if (*OutValue2 == NULL)

            *OutValue2 = new Transaction_rv_Array();

      else

            (*OutValue2)->clear();

      m_pCall->getCmplxArray(*OutValue2, (void*)
Axis_DeSerialize_Transaction_rv, (void*) Axis_Create_Transaction_rv, (void*)
Axis_Delete_Transaction_rv, "transaction_rv", Axis_URI_Transaction_rv);

    }

    else

    {

      // Unable to return value, but will deserialize to ensure subsequent
elements can be correctly processed.

      Transaction_rv_Array * pTemp2 = new Transaction_rv_Array();

      m_pCall->getCmplxArray(pTemp2, (void*)
Axis_DeSerialize_Transaction_rv, (void*) Axis_Create_Transaction_rv, (void*)
Axis_Delete_Transaction_rv, "transaction_rv", Axis_URI_Transaction_rv);

      delete pTemp2;

    }

  }

}

 

 

My code is inside the 'if (OutValue2 != NULL)' after it clears OutValue2 and
tries to getCmplxArray(). If I step into, I eventually step into
XMLParserXerces::parse (bool ignoreWhitespace, bool peekIt). In this code,
m_Xhandler.getAnyElement(); is called and returns a whitespace element, on
the second attempt, the account_login_rv element is returned.

 

It seems that parseNext() is being called too many times.

 

Here is my stack trace for when I have account_login_rv in elem (I inserted
newlines to make it easier to read).

XMLParserXerces::parse(unsigned char 1, unsigned char 1) line 133

 

XMLParserXerces::peek() line 222 + 12 bytes

 

axiscpp::SoapDeSerializer::getCmplxArray(axiscpp::SoapDeSerializer * const
0x003ed390, axiscpp::Axis_Array * 0x00516980, void * 0x100dc7d0
Axis_DeSerialize_Transaction_rv(Transaction_rv *,
axiscpp::IWrapperSoapDeSerializer *), void * 0x100ddd40
Axis_Create_Transaction_rv(int), void * 0x100dde60
Axis_Delete_Transaction_rv(Transaction_rv *, int), const char * ...) line
681 + 19 bytes

 

axiscpp::Call::getCmplxArray(axiscpp::Call * const 0x003e2738,
axiscpp::Axis_Array * 0x00516980, void * 0x100dc7d0
Axis_DeSerialize_Transaction_rv(Transaction_rv *,
axiscpp::IWrapperSoapDeSerializer *), void * 0x100ddd40
Axis_Create_Transaction_rv(int), void * 0x100dde60
Axis_Delete_Transaction_rv(Transaction_rv *, int), const char * 0x1070db9c
`string', const char * ...) line 457 

 

Soap::exec(Transaction_Array * 0x0012fe54, Fatal_err_rv * * 0x0012fd50,
Trans_abort_rv * * 0x0012fd48, Transaction_rv_Array * * 0x0012fd40) line 111

 

RNOWUtil::RunTransaction(Transaction_Array * 0x0012fe54) line 2176

 

RNOWUtil::login(const char * 0x00414044 `string', const char * 0x00414044
`string') line 1721 + 12 bytes

 

main(int 1, char * * 0x003e2440) line 17 + 21 bytes

 

mainCRTStartup() line 338 + 17 bytes

 

KERNEL32! 7c816fd7()

 

-Ryan

 

Ryan McCullough | RightNow Technologies | Integration Tools Engineer

406-556-3162 office | Bozeman, MT |  <mailto:rmccullough@rightnow.com>
rmccullough@rightnow.com |  <http://www.rightnow.com/>
http://www.rightnow.com

 


Mime
View raw message