nicklockwood / XMLDictionary

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

support duplicated tags? #27

Open caijingbo opened 9 years ago

caijingbo commented 9 years ago

i have a xml file like that:

<?xml version="1.0"  encoding="UTF-8"?>
<root xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
    <person id="1" value="a">
        <firstName>zhang</firstName>
        <lastName>sansan</lastName>string after element lastname
        <age>21
            <china>23</china>
            <zhou>21</zhou>
        </age>
    </person>
    <person id="2" value="b">
        <firstName>li</firstName>
        <lastName>sisisi</lastName>
        <age>31</age>
    </person>string after element person
    <man  value="b">
        <firstName>li</firstName>
        <lastName>sisisi</lastName>
        <age>21
            <china>23</china>
            <zhou>21</zhou>
        </age>
    </man>
    <woman type="white"/>
</root>

when i use like below: NSDictionary *personXml=[NSDictionary dictionaryWithXMLFile:xmlFilePath]; NSLog(@"personXml: %@", personXml); NSLog(@"path value[%@]",[personXml stringValueForKeyPath:@"person.age.china"]);

it generate a NSUnknownKeyException: 2014-10-26 14:39:07.098 XMLTest[1215:70b] *\ Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0xeb1f660> valueForUndefinedKey:]: this class is not key value coding-compliant for the key china.

i think it should be a duplicated tags problem, is it right?

caijingbo commented 9 years ago

default

nicklockwood commented 9 years ago

The problem is down to the structure of the XML. XMLDictionary handles multiple nodes with the same name - the problem here is that they have different structures.

For the first <person> node, age contains the value "21" and also two subsides, so XMLDictionary converts it to a dictionary. For the second <person> node, it only contains "21" and no subsides, so XMLDictionary collapses it to a string.

When you use the @"person.age.china" key path, it attempts to return an array containing the china property of both age nodes, but since the second age node is just a string, and doesn't have a china subnode, it crashes.

I can probably add some protection in the code for this scenario, but for now you can fix it by setting:

[XMLDictionaryParser sharedInstance].collapseTextNodes = NO;

Before parsing the XML.

nicklockwood commented 9 years ago

Note: if you want to retrieve an array of values for all person nodes, not just the first one, use this instead:

NSLog(@"path value[%@]", [personXml valueForKeyPath:@"person.age.china.__text"]);
maulikpat commented 8 years ago

@nicklockwood is this library supports below format :

screen shot 2016-06-08 at 7 55 34 pm