"Namespace prefix ... is not defined" & "Invalid root element" errors when using fetchEntryByUpdatingEntry:forEntryURL:delegate:didFinishSelector:

462 views
Skip to first unread message

Morgan Aldridge

unread,
Mar 6, 2013, 6:23:39 PM3/6/13
to gdata-objec...@googlegroups.com
As you may have caught on by this point, I've ported the Provisioning API to the GData Objective-C Client Library. It's been working well, but I just noticed one place where I had accidentally used fetchEntryWithURL:delegate:didFinishSelector: instead of fetchEntryByUpdatingEntry:forEntryURL:delegate:didFinishSelector: when working with my GDataEntryBase subclass for Group entries. Switching it over now results in the following errors:

    -:1: namespace error : Namespace prefix apps on property is not defined
    domain.tld</id><apps:property name="groupId" value="grou...@domain.tld"
    -:1: namespace error : Namespace prefix apps on property is not defined
    ain.tld"></apps:property><apps:property name="groupName" value="Group Name"
    -:1: namespace error : Namespace prefix apps on property is not defined
    Group Name"></apps:property><apps:property name="emailPermission" value="Domain"
    -:1: namespace error : Namespace prefix apps on property is not defined
    e="Domain"></apps:property><apps:property name="permissionPreset" value="Custom"
    -:1: namespace error : Namespace prefix apps on property is not defined
    reset" value="Custom"></apps:property><apps:property name="description" value=""
    2013-03-06 17:10:00.886 My App Name[57390:c03] Could not parse error: Error Domain=NSXMLParserErrorDomain Code=4 "Line 1: Document is empty
    " UserInfo=0x6a5a600 {NSLocalizedDescription=Line 1: Document is empty
    }
      Error XML data: [Line 1, Column 155] Invalid root element, expected (namespace uri:local name) of (http://www.w3.org/2005/Atom:entry), found (:entry

This is when taking a single group entry returned by my group feed and immediately update it with no changes. The entry from the fetch feed XML response is as follows:

    <entry xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;D0UHR347fip7ImA9WhBRFk0.&quot;">
        <updated>2013-03-06T21:27:16.006Z</updated>
        <app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-06T21:27:16.006Z</app:edited>
        <link rel="self" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/group/2.0/domain.tld/groupname%40domain.tld"/>
        <link rel="edit" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/group/2.0/domain.tld/groupname%40domain.tld"/>
        <apps:property name="groupId" value="grou...@domain.tld"/>
        <apps:property name="groupName" value="Group Name"/>
        <apps:property name="emailPermission" value="Domain"/>
        <apps:property name="permissionPreset" value="Custom"/>
        <apps:property name="description" value=""/>
    </entry>

I am able to correctly read the properties from my GDataEntryBase subclass, so it's parsing it correctly and understanding the namespaces. However, when I run fetchEntryByUpdatingEntry:forEntryURL:delegate:didFinishSelector: on the unchanged object (and the aforementioned errors are displayed), the following is the request XML that is actually sent (note the lack of the 'apps' namespace on the property elements, due to the errors):

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
      <entry xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;D0UHR347fip7ImA9WhBRFk0.&quot;">
      <property name="groupId" value="grou...@domain.tld"/>
      <property name="groupName" value="Group Name"/>
      <app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-06T21:27:16.006Z</app:edited>
      <link rel="self" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/group/2.0/domain.tld/groupname%40domain.tld"/>
      <link rel="edit" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/group/2.0/domain.tld/groupname%40domain.tld"/>
      <updated>2013-03-06T21:27:16.006Z</updated>
    </entry>

And the XML response I get back is the following truncated error:

    [Line 1, Column 155] Invalid root element, expected (namespace uri:local name) of (http://www.w3.org/2005/Atom:entry), found (:entry

I've been pouring through my code and am not seeing any difference between my working user GDataEntryBase subclass and broken group GDataEntryBase subclass, nor any difference between my working GDataObject subclasses which are used for 'apps:login', 'apps:name', 'apps:nickname', etc., elements and the apparently broken (but working for other fetches) GDataObject subclass for 'apps:property' elements.

I have noticed that while 'entry' elements from working user fetch feeds do not have the namespace URL attributes specified, for example:

<entry gd:etag="W/&quot;YDwqeyI.&quot;"> <id>https://apps-apis.google.com/a/feeds/domain.tld/user/2.0/username</id> <updated>1970-01-01T00:00:00.000Z</updated> <app:edited xmlns:app="http://www.w3.org/2007/app">1970-01-01T00:00:00.000Z</app:edited> <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/apps/2006#user"/> <title>username</title> <link rel="self" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/domain.tld/user/2.0/username"/> <link rel="edit" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/domain.tld/user/2.0/username"/> <apps:login userName="username" suspended="false" ipWhitelisted="false" admin="false" changePasswordAtNextLogin="false" agreedToTerms="true"/> <apps:quota limit="25600"/> <apps:name familyName="Name" givenName="User"/> <gd:feedLink rel="http://schemas.google.com/apps/2006#user.nicknames" href="https://apps-apis.google.com/a/feeds/domain.tld/nickname/2.0?username=username"/> <gd:feedLink rel="http://schemas.google.com/apps/2006#user.emailLists" href="https://apps-apis.google.com/a/feeds/domain.tld/emailList/2.0?recipient=username%40domain.tld"/> </entry>

The namespace URLs are automatically added to the 'entry' element when using fetchEntryByUpdatingEntry:forEntryURL:delegate:didFinishSelector:, for example:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
      <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" xmlns:app="http://www.w3.org/2007/app" xmlns:apps="http://schemas.google.com/apps/2006" gd:etag="W/&quot;YDwqeyI.&quot;">
      <apps:quota limit="25600"/>
      <app:edited xmlns:app="http://www.w3.org/2007/app">1970-01-01T00:00:00.000Z</app:edited>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <apps:login agreedToTerms="true" changePasswordAtNextLogin="false" userName="username" ipWhitelisted="false" suspended="false" admin="false"/>
      <link rel="self" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/domain.tld/user/2.0/username"/>
      <link rel="edit" type="application/atom+xml" href="https://apps-apis.google.com/a/feeds/domain.tld/user/2.0/username"/>
      <apps:name familyName="Name" givenName="User"/>
      <title>username</title>
    </entry>

However, in the failing use of fetchEntryByUpdatingEntry:forEntryURL:delegate:didFinishSelector: with the group GDataEntryBase subclass (the one with the namespace errors), those namespace URL attributes are not being automatically added to the 'entry' element.

Any tips as to where things might be going wrong would be _greatly_ appreciated as I'm having a horrendous time tracing this particular issue.

Morgan Aldridge

unread,
Mar 8, 2013, 2:09:31 PM3/8/13
to gdata-objec...@googlegroups.com
Any tips as to why the namespace might not be coming through?
 

Greg Robbins

unread,
Mar 10, 2013, 7:15:57 AM3/10/13
to gdata-objec...@googlegroups.com
The upload fetch methods use addNamespacesIfNoneToObject: to add a minimal set of standard namespaces if the entry being uploaded does not have any namespaces set, but that is just intended as a fallback and includes only the most common namespaces. Entries being uploaded should have the complete namespace dictionary specified.

The library's convenience methods for creating entries all call setNamespaces: to specify the namespaces for the entries being created.

Morgan Aldridge

unread,
Mar 11, 2013, 10:59:51 AM3/11/13
to gdata-objec...@googlegroups.com
On Sunday, March 10, 2013 7:15:57 AM UTC-4, Greg Robbins wrote:
The upload fetch methods use addNamespacesIfNoneToObject: to add a minimal set of standard namespaces if the entry being uploaded does not have any namespaces set, but that is just intended as a fallback and includes only the most common namespaces. Entries being uploaded should have the complete namespace dictionary specified.

The library's convenience methods for creating entries all call setNamespaces: to specify the namespaces for the entries being created.

Thanks, Greg.

Both my group GDataEntryBase subclass and my property GDataObject subclass (to support 'apps:property' elements) return the correct namespaces when the 'completeNamespaces' message is sent to them, but the former only returns the 'gd' namespace and the latter no namespaces when the 'namespace' message. In my debugging, I had passed through addNamespacesIfNoneToObject:, but it didn't apply anything since the 'gd' namespace is there.

I'll be continuing to pour over the GData framework source looking for hints, but at this point I'm still missing why 'completeNamespaces' isn't being used. I think that is what you're addressing, but I'm not sure what dictionary you're referring to. I've based my Google Apps classes heavily on the GData Calendar classes and haven't seen anything like this and can't seem to find what is different between this class and my other classes which upload without issue.

Thanks again for your assistance!

Greg Robbins

unread,
Mar 11, 2013, 6:52:38 PM3/11/13
to gdata-objec...@googlegroups.com
Namespaces must be explicitly added to entries when creating them for uploading. For example, the library's convenience method for creating a contact entry looks like this:

+ (GDataEntryContact *)contactEntryWithName:(GDataName *)name {
  GDataEntryContact *obj = [self object];
  [obj setNamespaces:[GDataContactConstants contactNamespaces]];
  [obj setName:name];
  return obj;
}

and the +contactNamespaces method provides a complete dictionary of standard namespaces along with the custom contacts namespace:

+ (NSDictionary *)contactNamespaces {
  NSMutableDictionary *namespaces;

  namespaces = [NSMutableDictionary dictionaryWithObject:kGDataNamespaceContact
                                                  forKey:kGDataNamespaceContactPrefix];

  [namespaces addEntriesFromDictionary:[GDataEntryBase baseGDataNamespaces]];

  return namespaces;
}

Morgan Aldridge

unread,
Mar 12, 2013, 5:03:07 PM3/12/13
to gdata-objec...@googlegroups.com
Yup, I have the appropriate creation convenience and namespace methods implemented for my classes.

So what you're saying is that even though the fetched entries are fetched, objects created, and appropriate namespaces set (and this works for my other classes), I need to explicitly set the namespaces before upload? I will give that a shot.

Greg Robbins

unread,
Mar 12, 2013, 11:38:43 PM3/12/13
to gdata-objec...@googlegroups.com
Entries obtained from the server are typically obtained inside of a larger feed, with the namespaces set on the feed rather than on the individual entries. The entries are just inheriting the namespaces.

Since an entry is uploaded without being wrapped in a feed, the entry needs the namespaces set.

Morgan Aldridge

unread,
Mar 13, 2013, 11:21:03 AM3/13/13
to gdata-objec...@googlegroups.com
On Tuesday, March 12, 2013 11:38:43 PM UTC-4, Greg Robbins wrote:
Entries obtained from the server are typically obtained inside of a larger feed, with the namespaces set on the feed rather than on the individual entries. The entries are just inheriting the namespaces.

Since an entry is uploaded without being wrapped in a feed, the entry needs the namespaces set.

Okay, worked. I've updated my code to do that for my user class too which has even more complex namespaces, but was working without any change.

Thanks again!
Reply all
Reply to author
Forward
0 new messages