Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -26,13 +26,14 @@ static OF_INLINE OFString* transform_string(OFMutableString *cache, OFObject *handler) { - /* TODO: Support for xml:space */ - - [cache removeLeadingAndTrailingWhitespaces]; + [cache replaceOccurrencesOfString: @"\r\n" + withString: @"\n"]; + [cache replaceOccurrencesOfString: @"\r" + withString: @"\n"]; return [cache stringByXMLUnescapingWithHandler: handler]; } static OF_INLINE OFString* namespace_for_prefix(OFString *prefix, OFArray *namespaces) @@ -467,12 +468,11 @@ pool = [[OFAutoreleasePool alloc] init]; attr_ns = namespace_for_prefix( (attrPrefix != nil ? attrPrefix : prefix), namespaces); - attr_val = [cache - stringByXMLUnescapingWithHandler: self]; + attr_val = transform_string(cache, self); if (attrPrefix == nil && [attrName isEqual: @"xmlns"]) { [[namespaces lastObject] setObject: attr_val Index: tests/OFXMLParserTests.m ================================================================== --- tests/OFXMLParserTests.m +++ tests/OFXMLParserTests.m @@ -57,12 +57,11 @@ case 3: TEST(msg, et == TAG_END && [name isEqual: @"bar"] && prefix == nil && ns == nil && attrs == nil) break; case 4: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n"]) break; case 5: TEST(msg, et == TAG_START && [name isEqual: @"foobar"] && prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] && [attrs count] == 1 && @@ -71,12 +70,11 @@ [[attrs objectAtIndex: 0] namespace] == nil && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"urn:objfw:test:foobar"]) break; case 6: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 7: TEST(msg, et == TAG_START && [name isEqual: @"qux"] && prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] && [attrs count] == 1 && @@ -86,12 +84,11 @@ @"http://www.w3.org/2000/xmlns/"] && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"urn:objfw:test:foo"]) break; case 8: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 9: TEST(msg, et == TAG_START && [name isEqual: @"bla"] && [prefix isEqual: @"foo"] && [ns isEqual: @"urn:objfw:test:foo"] && @@ -106,12 +103,11 @@ [[[attrs objectAtIndex: 1] namespace] isEqual: @"urn:objfw:test:foo"] && [[[attrs objectAtIndex: 1] stringValue] isEqual: @"foo"]) break; case 10: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 11: TEST(msg, et == TAG_START && [name isEqual: @"blup"] && prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] && [attrs count] == 2 && @@ -129,12 +125,11 @@ case 12: TEST(msg, et == TAG_END && [name isEqual: @"blup"] && prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"]) break; case 13: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 14: TEST(msg, et == TAG_START && [name isEqual: @"bla"] && [prefix isEqual: @"bla"] && [ns isEqual: @"urn:objfw:test:bla"] && [attrs count] == 3 && @@ -159,12 +154,11 @@ TEST(msg, et == TAG_END && [name isEqual: @"bla"] && [prefix isEqual: @"bla"] && [ns isEqual: @"urn:objfw:test:bla"]) break; case 16: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 17: TEST(msg, et == TAG_START && [name isEqual: @"abc"] && prefix == nil && [ns isEqual: @"urn:objfw:test:abc"] && [attrs count] == 3 && @@ -187,36 +181,32 @@ case 18: TEST(msg, et == TAG_END && [name isEqual: @"abc"] && prefix == nil && [ns isEqual: @"urn:objfw:test:abc"]) break; case 19: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 20: TEST(msg, et == TAG_END && [name isEqual: @"bla"] && [prefix isEqual: @"foo"] && [ns isEqual: @"urn:objfw:test:foo"]) break; case 21: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 22: TEST(msg, et == COMMENT && [comment isEqual: @"commänt"]) break; case 23: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n "]) break; case 24: TEST(msg, et == TAG_END && [name isEqual: @"qux"] && prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"]) break; case 25: - /* FIXME: -[removeLeadingAndTrailingWhitespaces removes this */ - TEST(msg, et == STRING && [string isEqual: @""]) + TEST(msg, et == STRING && [string isEqual: @"\n"]) break; case 26: TEST(msg, et == TAG_END && [name isEqual: @"foobar"] && prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"]) break;