tianshanxuester / gdata-objectivec-client

Automatically exported from code.google.com/p/gdata-objectivec-client
Other
0 stars 0 forks source link

XMLData property misses attributes added to an element if the attributes are added after adding the element to parent element #78

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create root Element
2. Create GDataXMLDocument using root element
3.add sub element to root element
4. Now add attributes to that element
5. Call XMLData propertyy on doc object 

What is the expected output? What do you see instead?
The artributes added in step 4 are not part of XMLData Returned

What version of the product are you using? On what operating system?
iOS 4.1 on xcode

Please provide any additional information below.

Original issue reported on code.google.com by sureshscribnar on 2 Nov 2010 at 8:25

GoogleCodeExporter commented 9 years ago
Use this code below to test it out. It can be put in the first viewcontroller 
of the iPhone app.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    GDataXMLElement *elm = [GDataXMLNode elementWithName:@"Message"];
    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithRootElement:elm];
    [elm addAttribute:[GDataXMLNode attributeWithName:@"Version" stringValue:@"1.0"]];
    NSLog(@"XML is:%@", [[[NSString alloc] initWithData:[doc XMLData] encoding:NSUTF8StringEncoding] autorelease] );
    [doc release];
}

Original comment by sureshscribnar on 3 Nov 2010 at 11:29

GoogleCodeExporter commented 9 years ago
The output is XML is:<?xml version="1.0"?>
<Message/>

But the expected is including the added attribute

XML is:<?xml version="1.0"?>
<Message Version="1.0"/>

Original comment by sureshscribnar on 3 Nov 2010 at 11:30

GoogleCodeExporter commented 9 years ago
Alright, got it resolved. The issue is that GDataXMLNode.m internally copies 
xmlNode struct pointed by the passed in element/object to addChild and 
initWithRootElement methods. This seems to have been done to keep the 
namespaces same as parent node's namespace when copying new child nodes to a 
parent node; based on the implementation of GDataXMLNode.m file.  That means,

We can set the reference of the passed object's variable to new node by 
querying the doc/element to which the node was added as child. This way, the 
attributes we add to an element after adding that element to parent element are 
added to the copy struct object.

Below is the method given in comment 1 with one new line of code that re-refers 
to an element object that refers to copied struct of xmlNode. This fixes the 
issue.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    GDataXMLElement *elm = [GDataXMLNode elementWithName:@"Message"];
    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithRootElement:elm];

    elm = [doc rootElement]; //newline 1

    [elm addAttribute:[GDataXMLNode attributeWithName:@"Version" stringValue:@"1.0"]];
    NSLog(@"XML is:%@", [[[NSString alloc] initWithData:[doc XMLData] encoding:NSUTF8StringEncoding] autorelease] );
    [doc release];
}

Conclusion: So, its not completely object oriented code in GDataXMLNode as it 
uses struct internally to hold sub objects. Its how its supposed to work anyway 
as libxml2 is used; there is no pure object oriented way when using libxml2 as 
GDataXMLNode is not independent xml library. So, we need to query the doc 
object to get object reference of nodes to which we want to add properties or 
child nodes before adding the child nodes.

With this understanding, its not an issue but a design choice and lack of 
documentation for each method. So, it would be good if these details are added 
as part of GDataXMLNode documentation for each method in that file. Lack of 
documentation means many developers may have to rediscover the same things over 
and over again.  

Note: I'm not sure if I can add this documentation in google code; if possible, 
I will in few days. Thanks for this wonderful library by the way. Cheers.

Original comment by sureshscribnar on 3 Nov 2010 at 12:30

GoogleCodeExporter commented 9 years ago
Thanks for the suggestion. I have added comments to the methods that copy their 
arguments.

http://code.google.com/p/gdata-objectivec-client/source/detail?r=596

Original comment by gregrobbins on 9 Nov 2010 at 10:35