@@ -71,11 +71,10 @@ } @end @implementation OFXMLElement @synthesize name = _name, namespace = _namespace; -@synthesize defaultNamespace = _defaultNamespace; + (instancetype)elementWithName: (OFString *)name { return [[[self alloc] initWithName: name] autorelease]; } @@ -209,12 +208,10 @@ self = [self initWithName: element->_name namespace: element->_namespace]; @try { - [_defaultNamespace release]; - _defaultNamespace = [element->_defaultNamespace retain]; [_attributes release]; _attributes = [element->_attributes retain]; [_namespaces release]; _namespaces = [element->_namespaces retain]; [_children release]; @@ -263,12 +260,10 @@ self = [self initWithName: element->_name namespace: element->_namespace]; @try { - [_defaultNamespace release]; - _defaultNamespace = [element->_defaultNamespace retain]; [_attributes release]; _attributes = [element->_attributes retain]; [_namespaces release]; _namespaces = [element->_namespaces retain]; [_children release]; @@ -309,15 +304,10 @@ OFXMLElement *attributesElement, *namespacesElement; OFXMLElement *childrenElement; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; - [_defaultNamespace release]; - _defaultNamespace = nil; - _defaultNamespace = [[element attributeForName: - @"defaultNamespace"].stringValue copy]; - attributesElement = [[element elementForName: @"attributes" namespace: OFSerializationNS] elementsForNamespace: OFSerializationNS].firstObject; namespacesElement = [[element @@ -388,11 +378,10 @@ - (void)dealloc { [_name release]; [_namespace release]; - [_defaultNamespace release]; [_attributes release]; [_namespaces release]; [_children release]; [super dealloc]; @@ -445,28 +434,22 @@ [ret makeImmutable]; return ret; } -- (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent - namespaces: (OFDictionary *)allNS - indentation: (unsigned int)indentation - level: (unsigned int)level OF_DIRECT +- (OFString *)of_XMLStringWithDefaultNS: (OFString *)defaultNS + namespaces: (OFDictionary *)allNS + indentation: (unsigned int)indentation + level: (unsigned int)level OF_DIRECT { void *pool; char *cString; size_t length, i; - OFString *prefix, *parentPrefix; - OFString *ret; - OFString *defaultNS; + OFString *prefix, *ret; pool = objc_autoreleasePoolPush(); - parentPrefix = [allNS objectForKey: - (parent != nil && parent->_namespace != nil - ? parent->_namespace : (OFString *)@"")]; - /* Add the namespaces of the current element */ if (allNS != nil) { OFEnumerator *keyEnumerator = [_namespaces keyEnumerator]; OFEnumerator *objectEnumerator = [_namespaces objectEnumerator]; OFMutableDictionary *tmp; @@ -483,17 +466,10 @@ allNS = _namespaces; prefix = [allNS objectForKey: (_namespace != nil ? _namespace : (OFString *)@"")]; - if (parent != nil && parent->_namespace != nil && parentPrefix == nil) - defaultNS = parent->_namespace; - else if (parent != nil && parent->_defaultNamespace != nil) - defaultNS = parent->_defaultNamespace; - else - defaultNS = _defaultNamespace; - i = 0; length = _name.UTF8StringLength + 3 + (level * indentation); cString = OFAllocMemory(length, 1); @try { @@ -501,11 +477,11 @@ i += level * indentation; /* Start of tag */ cString[i++] = '<'; - if (prefix != nil && ![_namespace isEqual: defaultNS]) { + if (prefix.length > 0) { length += prefix.UTF8StringLength + 1; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); @@ -515,22 +491,23 @@ memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); i += _name.UTF8StringLength; /* xmlns if necessary */ - if (prefix == nil && ((_namespace != nil && - ![_namespace isEqual: defaultNS]) || - (_namespace == nil && defaultNS != nil))) { + if (prefix.length == 0 && defaultNS != _namespace && + ![defaultNS isEqual: _namespace]) { length += _namespace.UTF8StringLength + 9; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, " xmlns='", 8); i += 8; memcpy(cString + i, _namespace.UTF8String, _namespace.UTF8StringLength); i += _namespace.UTF8StringLength; cString[i++] = '\''; + + defaultNS = _namespace; } /* Attributes */ for (OFXMLAttribute *attribute in _attributes) { void *pool2 = objc_autoreleasePoolPush(); @@ -543,12 +520,12 @@ attribute.stringValue.stringByXMLEscaping; char delimiter = (attribute->_useDoubleQuotes ? '"' : '\''); if (attribute->_namespace != nil && - (attributePrefix = [allNS objectForKey: - attribute->_namespace]) == nil) + [(attributePrefix = [allNS objectForKey: + attribute->_namespace]) length] == 0) @throw [OFUnboundNamespaceException exceptionWithNamespace: attribute.namespace element: self]; length += attributeNameLength + (attributePrefix != nil @@ -603,19 +580,21 @@ if (ind) [tmp addItem: "\n"]; if ([child isKindOfClass: [OFXMLElement class]]) childString = [(OFXMLElement *)child - of_XMLStringWithParent: self - namespaces: allNS - indentation: ind - level: level + 1]; - else - childString = [child - XMLStringWithIndentation: ind - level: level + - 1]; + of_XMLStringWithDefaultNS: defaultNS + namespaces: allNS + indentation: ind + level: level + + 1]; + else { + childString = child.XMLString; + for (unsigned int j = 0; + j < ind * (level + 1); j++) + [tmp addItem: " "]; + } [tmp addItems: childString.UTF8String count: childString.UTF8StringLength]; } @@ -636,11 +615,11 @@ i += level * indentation; } cString[i++] = '<'; cString[i++] = '/'; - if (prefix != nil) { + if (prefix.length > 0) { length += prefix.UTF8StringLength + 1; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); @@ -666,31 +645,31 @@ return ret; } - (OFString *)XMLString { - return [self of_XMLStringWithParent: nil - namespaces: nil - indentation: 0 - level: 0]; + return [self of_XMLStringWithDefaultNS: nil + namespaces: nil + indentation: 0 + level: 0]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { - return [self of_XMLStringWithParent: nil - namespaces: nil - indentation: indentation - level: 0]; + return [self of_XMLStringWithDefaultNS: nil + namespaces: nil + indentation: indentation + level: 0]; } -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level +- (OFString *)XMLStringWithDefaultNamespace: (OFString *)defaultNS + indentation: (unsigned int)indentation { - return [self of_XMLStringWithParent: nil - namespaces: nil - indentation: indentation - level: level]; + return [self of_XMLStringWithDefaultNS: defaultNS + namespaces: nil + indentation: indentation + level: 0]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); @@ -704,14 +683,10 @@ if (_namespace != nil) [element addAttributeWithName: @"namespace" stringValue: _namespace]; - if (_defaultNamespace != nil) - [element addAttributeWithName: @"defaultNamespace" - stringValue: _defaultNamespace]; - if (_attributes != nil) { OFXMLElement *attributesElement; attributesElement = [OFXMLElement elementWithName: @"attributes" @@ -856,12 +831,10 @@ - (void)setPrefix: (OFString *)prefix forNamespace: (OFString *)namespace { if (prefix.length == 0) @throw [OFInvalidArgumentException exception]; - if (namespace == nil) - namespace = @""; [_namespaces setObject: prefix forKey: namespace]; } - (void)bindPrefix: (OFString *)prefix forNamespace: (OFString *)namespace @@ -1036,13 +1009,10 @@ if (element->_name != _name && ![element->_name isEqual: _name]) return false; if (element->_namespace != _namespace && ![element->_namespace isEqual: _namespace]) return false; - if (element->_defaultNamespace != _defaultNamespace && - ![element->_defaultNamespace isEqual: _defaultNamespace]) - return false; if (element->_attributes != _attributes && ![element->_attributes isEqual: _attributes]) return false; if (element->_namespaces != _namespaces && ![element->_namespaces isEqual: _namespaces]) @@ -1060,11 +1030,10 @@ OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, _namespace.hash); - OFHashAddHash(&hash, _defaultNamespace.hash); OFHashAddHash(&hash, _attributes.hash); OFHashAddHash(&hash, _namespaces.hash); OFHashAddHash(&hash, _children.hash); OFHashFinalize(&hash); @@ -1076,11 +1045,10 @@ { OFXMLElement *copy = [[OFXMLElement alloc] of_init]; @try { copy->_name = [_name copy]; copy->_namespace = [_namespace copy]; - copy->_defaultNamespace = [_defaultNamespace copy]; copy->_attributes = [_attributes mutableCopy]; copy->_namespaces = [_namespaces mutableCopy]; copy->_children = [_children mutableCopy]; } @catch (id e) { [copy release];