/JMRXMLNode.m

http://rtm2cocoa.googlecode.com/ · Objective C · 181 lines · 136 code · 36 blank · 9 comment · 16 complexity · 36a7a32e6700d596d8413d5af8c29ba7 MD5 · raw file

  1. //
  2. // JMRXMLNode.m
  3. /*
  4. This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit http://creativecommons.org/licenses/by/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
  5. */
  6. #import "JMRXMLNode.h"
  7. @implementation JMRXMLNode
  8. -(id)initWithCFXMLNodeRef:(CFXMLNodeRef)nodeRef {
  9. [super init];
  10. if (nodeRef) {
  11. CFRetain(nodeRef);
  12. _xmlNode = nodeRef;
  13. return self;
  14. }
  15. return nil;
  16. }
  17. -(id)initWithString:(NSString *)string type:(int)type info:(CFXMLElementInfo *)info {
  18. CFXMLNodeRef ref = CFXMLNodeCreate(kCFAllocatorDefault,
  19. type, (CFStringRef)string, info,
  20. kCFXMLNodeCurrentVersion);
  21. return [self initWithCFXMLNodeRef:ref];
  22. }
  23. -(id)initWithName:(NSString *)tagName {
  24. CFXMLElementInfo *info = (CFXMLElementInfo *)malloc(sizeof(CFXMLElementInfo));
  25. // keep references to these
  26. info->attributes = (CFDictionaryRef)[self getAttributes];
  27. info->attributeOrder = (CFArrayRef)[self getAttributeOrder];
  28. info->isEmpty = NO;
  29. return [self initWithString:tagName type:kCFXMLNodeTypeElement info:info];
  30. }
  31. -(id)initWithText:(NSString *)text {
  32. return [self initWithString:text type:kCFXMLNodeTypeText info:NULL];
  33. }
  34. -(id)initWithWhitespace:(NSString *)text {
  35. return [self initWithString:text type:kCFXMLNodeTypeWhitespace info:NULL];
  36. }
  37. -(id)initWithCdata:(NSString *)cdata {
  38. return [self initWithString:cdata type:kCFXMLNodeTypeCDATASection info:NULL];
  39. }
  40. +(JMRXMLNode *)nodeWithCFXMLNodeRef:(CFXMLNodeRef)nodeRef {
  41. return [[[JMRXMLNode alloc] initWithCFXMLNodeRef:nodeRef] autorelease];
  42. }
  43. +(JMRXMLNode *)nodeWithName:(NSString *)tagName {
  44. return [[[JMRXMLNode alloc] initWithName:tagName] autorelease];
  45. }
  46. +(JMRXMLNode *)nodeWithText:(NSString *)text {
  47. return [[[JMRXMLNode alloc] initWithText:text] autorelease];
  48. }
  49. +(JMRXMLNode *)nodeWithCdata:(NSString *)cdata {
  50. return [[[JMRXMLNode alloc] initWithText:cdata] autorelease];
  51. }
  52. -(CFXMLNodeRef)nodeRef {
  53. return _xmlNode;
  54. }
  55. -(CFXMLElementInfo *)info {
  56. if (_xmlNode)
  57. return (CFXMLElementInfo *)CFXMLNodeGetInfoPtr(_xmlNode);
  58. return nil;
  59. }
  60. -(NSMutableDictionary *)getAttributes {
  61. CFXMLElementInfo *info;
  62. if (_xmlNode && ![self isElement])
  63. return nil;
  64. if (!_attributes) {
  65. info = [self info];
  66. [self setAttributes:((info && info->attributes) ?
  67. [NSMutableDictionary dictionaryWithDictionary:(NSDictionary *)info->attributes] :
  68. [NSMutableDictionary dictionary])];
  69. // need to allocate attribute order, too
  70. [self getAttributeOrder];
  71. }
  72. return _attributes;
  73. }
  74. -(void)setAttributes:(NSMutableDictionary *)value {
  75. CFXMLElementInfo *info = [self info];
  76. [value retain];
  77. [_attributes release];
  78. _attributes = value;
  79. if (info)
  80. info->attributes = (CFDictionaryRef)_attributes;
  81. }
  82. -(NSMutableArray *)getAttributeOrder {
  83. CFXMLElementInfo *info;
  84. if (_xmlNode && ![self isElement])
  85. return nil;
  86. if (!_attributeOrder) {
  87. info = [self info];
  88. [self setAttributeOrder:((info && info->attributeOrder) ?
  89. [NSMutableArray arrayWithArray:(NSArray *)info->attributeOrder] :
  90. [NSMutableArray array])];
  91. }
  92. return _attributeOrder;
  93. }
  94. -(void)setAttributeOrder:(NSMutableArray *)value {
  95. CFXMLElementInfo *info = [self info];
  96. [value retain];
  97. [_attributeOrder release];
  98. _attributeOrder = value;
  99. if (info)
  100. info->attributeOrder = (CFArrayRef)_attributeOrder;
  101. }
  102. -(NSString *)getAttributeForKey:(NSString *)key {
  103. return [[self getAttributes] objectForKey:key];
  104. }
  105. -(void)setAttribute:(NSString *)value forKey:(NSString *)key {
  106. if (!value) {
  107. [[self getAttributeOrder] removeObject:key];
  108. [[self getAttributes] removeObjectForKey:key];
  109. } else {
  110. if (![[self getAttributeOrder] containsObject:key])
  111. [[self getAttributeOrder] addObject:key];
  112. [[self getAttributes] setObject:value forKey:key];
  113. }
  114. }
  115. -(NSString *)getString {
  116. return (NSString *)CFXMLNodeGetString(_xmlNode);
  117. }
  118. -(BOOL)isType:(int)type {
  119. return _xmlNode && CFXMLNodeGetTypeCode(_xmlNode)==type;
  120. }
  121. -(BOOL)isElement {
  122. return [self isType:kCFXMLNodeTypeElement];
  123. }
  124. -(BOOL)isComment {
  125. return [self isType:kCFXMLNodeTypeComment];
  126. }
  127. -(BOOL)isProcessingInstruction {
  128. return [self isType:kCFXMLNodeTypeProcessingInstruction];
  129. }
  130. -(BOOL)isText {
  131. return [self isType:kCFXMLNodeTypeText];
  132. }
  133. -(BOOL)isCdata {
  134. return [self isType:kCFXMLNodeTypeCDATASection];
  135. }
  136. -(BOOL)isDocument {
  137. return [self isType:kCFXMLNodeTypeDocument];
  138. }
  139. -(void)dealloc {
  140. CFRelease(_xmlNode);
  141. [super dealloc];
  142. }
  143. @end