Problem with CFXMLCreateStringByEscapingEntities to replace special xml chars?

  • Hello,
    I've used CFXMLCreateStringByUnescapingEntities before with no
    problems, but I'm getting a consistent but unexpected result with
    CFXMLCreateStringByEscapingEntities now that I'm using it for the first
    time.  It seems that the returned string only includes up to the last
    replaced entity and cuts the rest of the string out and if there are no
    entities it returns an empty string.

    NSString* a = @"one < two";
    NSString* b = (NSString*)CFXMLCreateStringByEscapingEntities(
    kCFAllocatorDefault, (CFStringRef)a, NULL );
    NSLog( @"String \"%@\" became \"%@\"", a, b );

    Results in: String "one < two" became "one &lt;"

    Not much comes up when searching for
    CFXMLCreateStringByEscapingEntities, but is this a known behavior
    and/or bug?  Am I somehow doing something wrong here?

    Thanks for any thoughts or help,
    Ben Levy
  • Op 17-okt-04 om 6:58 heeft Benjamin Levy het volgende geschreven:

    > Hello,
    > I've used CFXMLCreateStringByUnescapingEntities before with no
    > problems, but I'm getting a consistent but unexpected result with
    > CFXMLCreateStringByEscapingEntities now that I'm using it for the
    > first time.  It seems that the returned string only includes up to the
    > last replaced entity and cuts the rest of the string out and if there
    > are no entities it returns an empty string.
    >
    > NSString* a = @"one < two";
    > NSString* b = (NSString*)CFXMLCreateStringByEscapingEntities(
    > kCFAllocatorDefault, (CFStringRef)a, NULL );
    > NSLog( @"String \"%@\" became \"%@\"", a, b );
    >
    > Results in: String "one < two" became "one &lt;"
    >
    > Not much comes up when searching for
    > CFXMLCreateStringByEscapingEntities, but is this a known behavior
    > and/or bug?  Am I somehow doing something wrong here?
    >

    Benjamin,

    I just checked the source for this function (in 10.3.5,
    <http://darwinsource.opendarwin.org/10.3.5/CF-299.31/Parsing.subproj/
    CFXMLParser.c
    >)  and it is indeed badly broken. You're better off
    writing a Cocoa replacement for now.

    There are two problems:
    1. the entities dictionary is ignored
    2. you will get a correct substring up to and including the final
    entity, but not what comes after

    The very crude, very slow and mostly untested code below at least fixes
    #2

    Regards

        Steven

    @implementation NSString (CBEscapeXMLEntities)

    - (NSString*) escapedString
    {
    NSMutableString* escaped = [[self mutableCopy] autorelease];// really,
    really broken (NSString*) ::CFXMLCreateStringByEscapingEntities (nil,
    (CFStringRef) self, nil);
    [escaped replaceOccurrencesOfString: @"&" withString: @"&amp;"
    options: 0 range: NSMakeRange (0, [escaped length])];
    [escaped replaceOccurrencesOfString: @"<" withString: @"&lt;" options:
    0 range: NSMakeRange (0, [escaped length])];
    [escaped replaceOccurrencesOfString: @">" withString: @"&gt;" options:
    0 range: NSMakeRange (0, [escaped length])];
    [escaped replaceOccurrencesOfString: @"\"" withString: @"&quot;"
    options: 0 range: NSMakeRange (0, [escaped length])];
    return [escaped copy];
    }

    @end

    --
    <steven...>
    http://sprintteam.com/