nicklockwood / XMLDictionary

[DEPRECATED]
http://charcoaldesign.co.uk/source/cocoa#xml-dictionary
Other
1.14k stars 235 forks source link

Removing key prefixes when using attributesMode=XMLDictionaryAttributesModeDiscard #19

Open gabebear opened 10 years ago

gabebear commented 10 years ago

When using XMLDictionaryAttributesModeDiscard I think the following XML should parse differently than it currently does.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <FindRoomsResponse xmlns="https://www.spa-booker.com/soap/business">
            <FindRoomsResult xmlns:a="https://www.spa-booker.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <a:ArgumentErrors i:nil="true" />
                <a:ErrorCode>0</a:ErrorCode>
                <a:ErrorMessage i:nil="true" />
                <a:IsSuccess>true</a:IsSuccess>
                <a:Results xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
                    <b:anyType i:type="a:Room">
                        <a:Capacity>100</a:Capacity>
                        <a:Description i:nil="true" />
                        <a:ID>65571</a:ID>
                        <a:LocationID i:nil="true" />
                        <a:Name>My Room</a:Name>
                        <a:Treatments>
                            <b:int>752012</b:int>
                            <b:int>1483258</b:int>
                        </a:Treatments>
                        <a:DateCreated>2013-01-14T16:32:00</a:DateCreated>
                        <a:DateLastModified>2013-01-14T16:32:00</a:DateLastModified>
                    </b:anyType>
                </a:Results>
                <a:TotalResultsCount>1</a:TotalResultsCount>
            </FindRoomsResult>
        </FindRoomsResponse>
    </s:Body>
</s:Envelope>

currently with XMLDictionaryAttributesModeDiscard it outputs:

{
    "__name" = "s:Envelope";
    "s:Body" =     {
        FindRoomsResponse =         {
            FindRoomsResult =             {
                "a:ErrorCode" = 0;
                "a:IsSuccess" = true;
                "a:Results" =                 {
                    "b:anyType" =                     {
                        "a:Capacity" = 100;
                        "a:DateCreated" = "2013-01-14T16:32:00";
                        "a:DateLastModified" = "2013-01-14T16:32:00";
                        "a:ID" = 65571;
                        "a:Name" = "My Room";
                        "a:Treatments" =                         {
                            "b:int" =                             (
                                752012,
                                1483258
                            );
                        };
                    };
                };
                "a:TotalResultsCount" = 1;
            };
        };
    };
}

I think the prefixed xmlns namespace prefixes on each element should be stripped like this:

{
    Body =     {
        FindRoomsResponse =         {
            FindRoomsResult =             {
                ErrorCode = 0;
                IsSuccess = true;
                Results =                 {
                    anyType =                     {
                        Capacity = 100;
                        DateCreated = "2013-01-14T16:32:00";
                        DateLastModified = "2013-01-14T16:32:00";
                        ID = 65571;
                        Name = "My Room";
                        Treatments =                         {
                            int =                             (
                                752012,
                                1483258
                            );
                        };
                    };
                };
                TotalResultsCount = 1;
            };
        };
    };
    "__name" = Envelope;
}

I made a simple change to the library to do this:

- (void)parser:(__unused NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(__unused NSString *)namespaceURI qualifiedName:(__unused NSString *)qName attributes:(NSDictionary *)attributeDict
{
    [self endText];

    if (_attributesMode==XMLDictionaryAttributesModeDiscard) {
        NSUInteger loc = [elementName rangeOfString:@":"].location;
        if (loc != NSNotFound) {
            elementName = [elementName substringFromIndex:loc + 1];
        }
    }

    NSMutableDictionary *node = [NSMutableDictionary dictionary];
    switch (_nodeNameMode)

Not sure if this should go into the mainline branch or not... seems correct to me.

nicklockwood commented 10 years ago

Yes, this seems like a sensible configuration option. Please make a pull request and I'll review it.

Thanks!

gabebear commented 10 years ago

created https://github.com/nicklockwood/XMLDictionary/pull/20

larryonoff commented 9 years ago

@nicklockwood could you please merge this pull request?