KanikaVarma / sudzc

Automatically exported from code.google.com/p/sudzc
0 stars 0 forks source link

TouchXML includes possible text as children #8

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
The touchxml library seems to be fumbling over the response it gets.  Here is 
the response:

<?xml version="1.0" encoding="UTF-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <env:Body>
    <n1:LoginResponse xmlns:n1="urn:securityxml"
        env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <return xsi:type="xsd:int">116</return>
    </n1:LoginResponse>
  </env:Body>
</env:Envelope>

the generated sudz code for getting the result like this (in 
connectionDidFinishLoading in SoapResponse.m):

        CXMLNode* element = [[Soap getNode: [doc rootElement] withName: @"Body"] childAtIndex:0];
        if(deserializeTo == nil) {
            output = [Soap deserialize:element];
        } else {
            if([deserializeTo respondsToSelector: @selector(initWithNode:)]) {
                element = [element childAtIndex:0];
                output = [deserializeTo initWithNode: element];
            } else {
                NSString* value = [[[element childAtIndex:0] childAtIndex:0] stringValue];
                output = [Soap convert: value toType: deserializeTo];
            }
        }

This wasn't working, and I found out it was because the childAtIndex:0 calls 
were returning the text property of the node. Maybe this is because the xml was 
formatted, so the text was a bunch of whitespace.  I had to change it to this:

        CXMLNode* element = [[Soap getNode: [doc rootElement] withName: @"Body"] childAtIndex:1];
        if(deserializeTo == nil) {
            output = [Soap deserialize:element];
        } else {
            if([deserializeTo respondsToSelector: @selector(initWithNode:)]) {
                element = [element childAtIndex:1];
                output = [deserializeTo initWithNode: element];
            } else {
                NSString* value = [[element childAtIndex:1] stringValue];
                output = [Soap convert: value toType: deserializeTo];
            }
        }

So it actually got the int value, instead of a bunch of whitespace where the 
child value turned out to be nil all the time.

Basically, childAtNode:0 will return inconsistant results, so you need a better 
way of getting the return value.

Original issue reported on code.google.com by toucansa...@gmail.com on 26 Jul 2010 at 8:17

GoogleCodeExporter commented 9 years ago
You are right with your observations, but this fix doesn't really help if you 
have a response with many subnodes containing whitespaces in their names. 
You'll always run into truouble if you try to work with child nodes.
After some search I found the solution by adding another xmlParserOption flag 
to the document creation.
In initWithData of CXMLDocument.m change the following line 

theDoc = xmlReadMemory([inData bytes], [inData length], NULL, enc, 
XML_PARSE_RECOVER | XML_PARSE_NOWARNING);

to this:

theDoc = xmlReadMemory([inData bytes], [inData length], NULL, enc, 
XML_PARSE_RECOVER | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS);

Now everthing should be nice and clean. Remember to change your lines in 
SoapResponse.m back to the way they used to be.

I hope this helps some people and saves them some headache.

Original comment by christop...@broadsupport.tv on 20 Jan 2012 at 6:44