Index: src/OFXMLAttribute.h ================================================================== --- src/OFXMLAttribute.h +++ src/OFXMLAttribute.h @@ -16,10 +16,11 @@ /** * \brief A representation of an attribute of an XML element as an object. */ @interface OFXMLAttribute: OFObject { +@public OFString *name; OFString *namespace; OFString *stringValue; } Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -50,10 +50,35 @@ return tmp; } return nil; } + +static OF_INLINE void +resolve_attr_namespace(OFXMLAttribute *attr, OFString *prefix, OFString *ns, + OFArray *namespaces, Class isa) +{ + OFString *attr_ns; + OFString *attr_prefix = attr->namespace; + + if ([[attr name] isEqual: @"xmlns"] && attr_prefix == nil) { + [attr->namespace release]; + attr->namespace = nil; + return; + } + + attr_ns = namespace_for_prefix( + (attr_prefix != nil ? attr_prefix : prefix), namespaces); + + if ((attr_prefix != nil && attr_ns == nil) || + (ns != nil && attr_ns == nil)) + @throw [OFUnboundNamespaceException newWithClass: isa + prefix: attr_prefix]; + + [attr->namespace release]; + attr->namespace = [attr_ns retain]; +} @implementation OFXMLParser + parser { return [[[self alloc] init] autorelease]; @@ -327,18 +352,24 @@ /* Inside a tag, name found */ case OF_XMLPARSER_IN_TAG: if (buf[i] == '>' || buf[i] == '/') { OFString *ns; + OFXMLAttribute **attrs_c = [attrs cArray]; + size_t j, attrs_cnt = [attrs count]; ns = namespace_for_prefix(prefix, namespaces); if (prefix != nil && ns == nil) @throw [OFUnboundNamespaceException newWithClass: isa prefix: prefix]; + for (j = 0; j < attrs_cnt; j++) + resolve_attr_namespace(attrs_c[j], + prefix, ns, namespaces, isa); + pool = [[OFAutoreleasePool alloc] init]; [delegate parser: self didStartElement: name withPrefix: prefix @@ -428,32 +459,26 @@ break; /* Looking for attribute value */ case OF_XMLPARSER_IN_ATTR_VALUE: if (buf[i] == delim) { - OFString *attr_ns; OFString *attr_val; len = i - last; if (len > 0) [cache appendCStringWithoutUTF8Checking: buf + last length: len]; pool = [[OFAutoreleasePool alloc] init]; - attr_ns = namespace_for_prefix( - (attrPrefix != nil ? attrPrefix : prefix), - namespaces); attr_val = transform_string(cache, self); if (attrPrefix == nil && - [attrName isEqual: @"xmlns"]) { + [attrName isEqual: @"xmlns"]) [[namespaces lastObject] setObject: attr_val forKey: @""]; - attr_ns = nil; - } if ([attrPrefix isEqual: @"xmlns"]) [[namespaces lastObject] setObject: attr_val forKey: attrName]; @@ -460,11 +485,11 @@ if (attrs == nil) attrs = [[OFMutableArray alloc] init]; [attrs addObject: [OFXMLAttribute attributeWithName: attrName - namespace: attr_ns + namespace: attrPrefix stringValue: attr_val]]; [pool release]; [cache setToCString: ""];