forked from tinycode/xmppframework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NSXMLElementAdditions.m
110 lines (96 loc) · 2.87 KB
/
NSXMLElementAdditions.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#import "NSXMLElementAdditions.h"
@implementation NSXMLElement (XMPPStreamAdditions)
/**
* Quick method to create an element
**/
+ (NSXMLElement *)elementWithName:(NSString *)name xmlns:(NSString *)ns
{
NSXMLElement *element = [NSXMLElement elementWithName:name];
[element setXmlns:ns];
return element;
}
/**
* This method returns the first child element for the given name (as an NSXMLElement).
* If no child elements exist for the given name, nil is returned.
**/
- (NSXMLElement *)elementForName:(NSString *)name
{
NSArray *elements = [self elementsForName:name];
if([elements count] > 0)
{
return [elements objectAtIndex:0];
}
else
{
// There is a bug in the NSXMLElement elementsForName: method.
// Consider the following XML fragment:
//
// <query xmlns="jabber:iq:private">
// <x xmlns="some:other:namespace"></x>
// </query>
//
// Calling [query elementsForName:@"x"] results in an empty array!
//
// However, it will work properly if you use the following:
// [query elementsForLocalName:@"x" URI:@"some:other:namespace"]
//
// The trouble with this is that we may not always know the xmlns in advance,
// so in this particular case there is no way to access the element without looping through the children.
//
// This bug was submitted to apple on June 1st, 2007 and was classified as "serious".
return nil;
}
}
/**
* This method returns the first child element for the given name and given xmlns (as an NSXMLElement).
* If no child elements exist for the given name and given xmlns, nil is returned.
**/
- (NSXMLElement *)elementForName:(NSString *)name xmlns:(NSString *)xmlns
{
NSArray *elements = [self elementsForLocalName:name URI:xmlns];
if([elements count] > 0)
{
return [elements objectAtIndex:0];
}
else
{
return nil;
}
}
/**
* Returns the common xmlns "attribute", which is only accessible via the namespace methods.
* The xmlns value is often used in jabber elements.
**/
- (NSString *)xmlns
{
return [[self namespaceForPrefix:@""] stringValue];
}
- (void)setXmlns:(NSString *)ns
{
// If we use setURI: then the xmlns won't be displayed in the XMLString.
// Adding the namespace this way works properly.
[self addNamespace:[NSXMLNode namespaceWithName:@"" stringValue:ns]];
}
/**
* Shortcut to avoid having to use NSXMLNode everytime
**/
- (void)addAttributeWithName:(NSString *)name stringValue:(NSString *)string
{
[self addAttribute:[NSXMLNode attributeWithName:name stringValue:string]];
}
/**
* Returns all the attributes in a dictionary.
**/
- (NSDictionary *)attributesAsDictionary
{
NSArray *attributes = [self attributes];
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:[attributes count]];
int i;
for(i = 0; i < [attributes count]; i++)
{
NSXMLNode *node = [attributes objectAtIndex:i];
[result setObject:[node stringValue] forKey:[node name]];
}
return result;
}
@end