Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions GDataXML-HTML/lib/GDataXMLNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ typedef NSUInteger GDataXMLNodeKind;
- (NSArray *)children;
- (GDataXMLNode *)childAtIndex:(unsigned)index;

- (GDataXMLNode *)parent;

- (NSUInteger)index;

- (NSString *)localName;
- (NSString *)name;
- (NSString *)prefix;
Expand Down Expand Up @@ -185,6 +189,7 @@ typedef NSUInteger GDataXMLNodeKind;
// addChild adds a copy of the child node to the element
- (void)addChild:(GDataXMLNode *)child;
- (void)removeChild:(GDataXMLNode *)child;
- (void)removeChildAtIndex:(NSUInteger)index;

- (NSArray *)elementsForName:(NSString *)name;
- (NSArray *)elementsForLocalName:(NSString *)localName URI:(NSString *)URI;
Expand All @@ -193,6 +198,7 @@ typedef NSUInteger GDataXMLNodeKind;
- (GDataXMLNode *)attributeForName:(NSString *)name;
- (GDataXMLNode *)attributeForLocalName:(NSString *)name URI:(NSString *)attributeURI;
- (void)addAttribute:(GDataXMLNode *)attribute;
- (void)removeAttributeForName:(NSString *)name;

- (NSString *)resolvePrefixForNamespaceURI:(NSString *)namespaceURI;

Expand Down
109 changes: 108 additions & 1 deletion GDataXML-HTML/lib/GDataXMLNode.m
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,68 @@ - (NSString *)stringFromXMLString:(const xmlChar *)chars {
return result;
}

/**
* Removes and free's the given attribute from its parent node.
* The attribute's surrounding prev/next pointers are properly updated to remove the attribute from the attr list.
**/
+ (void)removeAttribute:(xmlAttrPtr)attr
{
// We perform a bit of optimization here.
// No need to bother nullifying pointers since we're about to free the node anyway.
[self detachAttribute:attr andClean:NO];

xmlFreeProp(attr);
}

/**
* Detaches the given attribute from its parent node.
* The attribute's surrounding prev/next pointers are properly updated to remove the attribute from the attr list.
* Then, if the clean flag is YES, the attribute's parent, prev, next and doc pointers are set to null.
**/
+ (void)detachAttribute:(xmlAttrPtr)attr andClean:(BOOL)clean
{
xmlNodePtr parent = attr->parent;

// Update the surrounding prev/next pointers
if (attr->prev == NULL)
{
parent->properties = attr->next;
if (attr->next != NULL) {
attr->next->prev = NULL;
}
}
else
{
attr->prev->next = attr->next;
if (attr->next != NULL) {
attr->next->prev = attr->prev;
}
}

if (clean)
{
// Nullify pointers
attr->parent = NULL;
attr->prev = NULL;
attr->next = NULL;
attr->ns = NULL;
if (attr->doc != NULL) [self stripDocPointersFromAttr:attr];
}
}

+ (void)stripDocPointersFromAttr:(xmlAttrPtr)attr
{
xmlNodePtr child = attr->children;
while (child != NULL)
{
child->doc = NULL;
child = child->next;
}

attr->doc = NULL;
}


- (void)dealloc {

if (xmlNode_ && shouldFreeXMLNode_) {
Expand Down Expand Up @@ -652,6 +714,27 @@ - (GDataXMLNode *)childAtIndex:(unsigned)index {
return nil;
}

- (GDataXMLNode *)parent {
xmlNodePtr node = xmlNode_;

if (node->parent == NULL)
return nil;
else
return [GDataXMLNode nodeBorrowingXMLNode:node->parent];
}

- (NSUInteger)index {
NSUInteger result = 0;
xmlNodePtr node = xmlNode_->prev;
while (node != NULL)
{
result++;
node = node->prev;
}

return result;
}

- (GDataXMLNodeKind)kind {
if (xmlNode_ != NULL) {
xmlElementType nodeType = xmlNode_->type;
Expand Down Expand Up @@ -1115,6 +1198,11 @@ - (void)removeChild:(GDataXMLNode *)child {
}
}

- (void)removeChildAtIndex:(NSUInteger)index
{
[self removeChild:[self childAtIndex:index]];
}

- (NSArray *)elementsForName:(NSString *)name {

NSString *desiredName = name;
Expand Down Expand Up @@ -1326,6 +1414,26 @@ - (void)addAttribute:(GDataXMLNode *)attribute {
}
}

- (void)removeAttributeForName:(NSString *)name {
// This is a private/internal method

xmlAttrPtr attr = (xmlNode_)->properties;
if (attr)
{
const xmlChar *xmlName = (const xmlChar *)[name UTF8String];;
do
{
if (xmlStrEqual(attr->name, xmlName))
{
[GDataXMLNode removeAttribute:attr];
return;
}
attr = attr->next;

} while(attr);
}
}

- (GDataXMLNode *)attributeForXMLNode:(xmlAttrPtr)theXMLNode {
// search the cached attributes list for the GDataXMLNode with
// the underlying xmlAttrPtr
Expand Down Expand Up @@ -1981,4 +2089,3 @@ static CFHashCode StringCacheKeyHashCallBack(const void *str) {
}
return hash;
}