0

I have problem with parsing soap response using Sudzc (ARC branch). I have some WCF service which stores data for our apps. I managed to connect to web service I can get response successfully, however I got stuck when one of responses came with z:ref attribute. It is hard to explain without an example right ? ;) /i have replaced important data with for example "#someid" so do not point that it is a problem ;)

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
    <ActivityId>#some credentials </ActivityId>
</s:Header>
<s:Body>
    <GetMessagesResponse >
        <GetMessagesResult  xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <AllItemsCount>2</AllItemsCount>
            <Items>
                <Message z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
                    <GlobalId>#msgid</GlobalId>
                    <Content>bbbbbbbb</Content>
                    <CreatedDate>2013-02-14T16:33:07</CreatedDate>
                    <Priority>Normal</Priority>
                    <Receiver z:Id="i2">
                        <GlobalId>#receiverid</GlobalId>
                        <CountryId>37</CountryId>
                        <CreationDate>2013-01-31T16:12:40</CreationDate>
                        <Gender>Male</Gender>
                        <IsDeleted>false</IsDeleted>
                        <Picture i:nil="true" />
                        <UserName>tobiasz</UserName>
                    </Receiver>
                    <Sender z:Id="i3">
                        <GlobalId>#senderid</GlobalId>
                        <CountryId>6</CountryId>
                        <CreationDate>2013-02-04T13:08:40</CreationDate>
                        <Gender>Male</Gender>
                        <IsDeleted>false</IsDeleted>
                        <Picture >
                            #"picture info"
                        </Picture>
                        <UserName>tobiasz2</UserName>
                    </Sender>
                    <Topic>RE: 56765765</Topic>
                </Message>
                <Message z:Id="i4" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
                    <GlobalId>#msgid2</GlobalId>
                    <Content>aaaaaaa</Content>
                    <CreatedDate>2013-02-14T16:31:01</CreatedDate>
                    <Priority>High</Priority>
                    <Receiver z:Ref="i2"/>
                    <Sender z:Ref="i3"/>
                    <Topic>RE: 56765765</Topic>
                </Message>
            </Items>
            <PageIndex>0</PageIndex>
            <RetrievedDateTime>2013-02-15T13:14:57.0813487Z</RetrievedDateTime>
        </GetMessagesResult>
    </GetMessagesResponse>
</s:Body>

As You can see there are lines which identifies Receiver node as i2 and further You can see node of another message from the same sender and to the same receiver

sudzc generated class used to parse this xml:

@interface ResultOfGetMessages : SoapObject{
    int _AllItemsCount;
    NSMutableArray* _Items;
    int _PageIndex;
    NSDate* _RetrievedDateTime;
}

@interface Message : WSGlobalObject{
    NSString* _Content;
    NSDate* _CreatedDate;
    NSString* _Priority;
    User* _Receiver;
    User* _Sender;
    NSString* _Topic;
}

@interface User : WSGlobalObject{
    int _CountryId;
    NSDate* _CreationDate;
    NSString* _Gender;
    BOOL _IsDeleted;
    PictureInfo* _Picture;
    NSString* _UserName;
}

Sudz with Touchxml fails to read that (getting null receiver and sender), response is parsed as:

<ResultOfGetMessages>
<AllItemsCount>2</AllItemsCount>
<Items>
    <Message>
        <GlobalId>###</GlobalId>
        <Content>bbbbbbbb</Content>
        <CreatedDate>2013-02-14T16:33:07.000</CreatedDate>
        <Priority>Normal</Priority>
        <Receiver>
            <GlobalId>####</GlobalId>
            <CountryId>37</CountryId>
            <CreationDate>2013-01-31T16:12:40.000</CreationDate>
            <Gender>Male</Gender>
            <IsDeleted>false</IsDeleted>
            <Picture i:nil="true" ></Picture>
            <UserName>tobiasz</UserName>
            <Version>11</Version>
        </Receiver>
        <Sender>
            <GlobalId>e4bda93c-a11c-4ae2-baf1-a15b00e918e7</GlobalId>
            <CountryId>6</CountryId>
            <CreationDate>2013-02-04T13:08:40.000</CreationDate>
            <Gender>Male</Gender>
            <IsDeleted>false</IsDeleted>
            <Picture >
                ####
            </Picture>
            <UserName>tobiasz2</UserName>
            <Version>11</Version>
        </Sender>
        <Topic>RE: 56765765</Topic>
    </Message>
    <Message>
        <GlobalId>###</GlobalId>
        <Content>aaaaaaa</Content>
        <CreatedDate>2013-02-14T16:31:01.000</CreatedDate>
        <Priority>High</Priority>
        <Receiver>
            <CountryId>0</CountryId>
            <IsDeleted>false</IsDeleted>
        </Receiver>
        <Sender>
            <CountryId>0</CountryId>
            <IsDeleted>false</IsDeleted>
        </Sender>
        <Topic>RE: 56765765</Topic>
    </Message>
</Items>
<PageIndex>0</PageIndex>

I think problems lays in depth of deserialization. Parser (if) tries to get the receiver node with specified id however it fails because receiver node marked with this id is in other node (previous item node).

Thanks in advance for help and your time.

cbr
  • 1
  • 2

1 Answers1

0

I had a simular problem with the soap.m when it serialized the nodes. had to this code:

// Deserializes the element in a dictionary.
+(id)deserializeAsDictionary:(CXMLNode*)element {

if([element childCount] == 1) {
CXMLNode* child = [[element children] objectAtIndex:0];
if([child kind] == CXMLTextKind) 
{
     NSLog(@"The Child Node: %@", [[[element children] objectAtIndex:0] stringValue]);
    return [[[element children] objectAtIndex:0] stringValue];

}
}

NSMutableDictionary* d = [NSMutableDictionary dictionary];
for(CXMLNode* child in [element children]) {
id v = [Soap deserialize:child];
if(v == nil) { v = [NSNull null]; }
[d setObject:v forKey:[child name]];
}
return d;
}

to:

// Deserializes the element in a dictionary.
+(id)deserializeAsDictionary:(CXMLNode*)element {

if([element childCount] == 1) {
CXMLNode* child = [[element children] objectAtIndex:0];
if([child kind] == CXMLTextKind) 
{
     NSLog(@"The Child Node: %@", [[[element children] objectAtIndex:0] stringValue]);
    return [[[element children] objectAtIndex:0] stringValue];

}
}

NSMutableDictionary* d = [NSMutableDictionary dictionary];
for(CXMLNode* child in [element children]) {
id v = [Soap deserialize:child];
if(v == nil) { v = [NSNull null]; }
[d setObject:v forKey:[child name]];

if( check != nil ) {             
NSInteger next = 1;             
key = [NSString stringWithFormat:@"%@%04d", [child name], next];
check = [d objectForKey:key]; 
while( check != nil ) {                 
    next++; 
    key = [NSString stringWithFormat:@"%@%04d", [child name], next]; 
    check = [d objectForKey:key]; 
} 
[d setObject:v forKey:key]; 
} else {
[d setObject:v forKey:[child name]];
}
iDev
  • 478
  • 1
  • 3
  • 24
  • Tahnks for reply. I had figured to resolve this problem by collectiong nodes that have ID's and populate their data to nodes that are empty and has IDREF's. The data collected from ID'ed nodes are stored in DB. So kinda complicated comparing to Yours solution ;) I've read the code and it looks simple and promising. Now i'm developing other project, I'll gonna return to it probably in January'13 and i'm going to test Yours solution. Thanks again ! – cbr Nov 29 '13 at 12:40