iosiphoneobjective-cxmlnsxmlparser

iOS: NSXMLParser error on iOS 6 (code 100)


in my iOS application I make a call to the WS which returns an xml response. I parse it using NSXMLParser. Everything was working OK on iOS 6 until the webservice changed a little bit. Now I keep getting this error for iOS 6:

The following error has occurred: The operation couldn't be completed. (NSXMLParserErrorDomain error 100.) (code: 100)

But, when I tried on iOS 7 everything worked just fine. Below are the xml responses:

OLD xml response:

<User 
  xmlns="MyService.Rest.A3.Entities" 
  xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <FirstName>George</FirstName>
  <LastName>McQuillan</LastName>
  <Username>usename</Username>
</User>

NEW xml response:

<User 
   xmlns="http://www.MyService.Rest.A3.Entities" 
   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <FirstName>George</FirstName>
   <LastName>McQuillan</LastName>
   <Username>usename</Username>
</User>

So the new response works only on iOS 7, on iOS 6 it doesn't. I noticed that the first xmlns from old response is not a link, but why does it work for iOS 7 then?


Solution

  • I experience the exact opposite, where the xmlns="MyService.Rest.A3.Entities" rendition calls parseErrorOccurred in iOS 6, but not in iOS 7. And in my tests, the xmlns="http://www.MyService.Rest.A3.Entities" rendition succeeds in both iOS 6 and 7.

    NSXMLParser in iOS 6 appears to validate whether the namespace is a valid absolute URI. iOS 7 does not. The namespace with xmlns="MyService.Rest.A3.Entities" is not a valid absolute URI. If you run that through xmllint (a command line program available on the Mac via the Terminal app), it will also report that that namespace is not valid:

    $ xmllint old.xml 
    
    old.xml:2: namespace warning : xmlns: URI MyService.Rest.A3.Entities is not absolute
      xmlns="MyService.Rest.A3.Entities" 
                                        ^
    <?xml version="1.0"?>
    <User xmlns="MyService.Rest.A3.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <FirstName>George</FirstName>
      <LastName>McQuillan</LastName>
      <Username>usename</Username>
    </User>
    

    Fortunately this error is informational only, and the parsing continues, so if you're stuck with this XML, you might just want to gracefully detect and ignore it, e.g.:

    if (!([error.domain isEqualToString:NSXMLParserErrorDomain] && error.code == 100)) {
        // do your error handling here, ignoring `NSXMLParserErrorDomain` code 100
        NSLog(@"%@", error);
    }
    

    It's probably better to fix the XML so that it has a valid URI.


    By the way, the XML Namespaces Specification points out that the use of a relative URI has been deprecated and that a namespace value should either be empty or an absolute URI. So, it's understandable why iOS 6 reports the error, but given that parseErrorOccurred is intended for fatal errors only, the iOS 7 behavior is probably more correct, no longer calling this method for this non-fatal warning.