Читать, изменять, писать XML-файл в какао - PullRequest
9 голосов
/ 15 мая 2011

Я ищу краткий пример / учебник о том, как читать, изменять одно значение и писать XML-файл, используя какао. Все, что я нашел, это либо простой (только чтение или запись), либо комплексный (будучи полным редактором XML).

Это похоже на довольно стандартный сценарий использования, поэтому я надеюсь, что там что-то есть ...

Ответы [ 3 ]

6 голосов
/ 16 февраля 2013

Я ошибался, когда утверждал, что написание таких элементов невозможно. У Apple есть два парсера XML, один для NSDictionary / NSArray / NSString / NSNumber / и т. Д. объекты и один называется NSXMLDocument.

Я удалил предыдущий код, который был совместим с Mac OS X 10.3; код, упомянутый ниже, позволит вам иметь xml-файлы, содержащие любые теги и атрибуты, которые вам нравятся. В моем примере код создаст файл XML, который выглядит следующим образом:

1

Примечание. Вы можете даже удалить «counter» и переименовать «root» в «counter», если хотите уменьшить его еще больше.

Новый код совместим с Mac OS X 10.4 и выше; он протестирован и работает "из коробки":

- (void)incrementCounter
{
    NSXMLDocument   *xmlDoc;
    NSError         *error;
    NSURL           *url;
    NSXMLElement    *root;
    id              item;
    NSData          *data;
    NSArray         *children;
    int             counter;
    NSString        *pathname;

    pathname = [@"~/myFile" stringByExpandingTildeInPath];
    url = [NSURL fileURLWithPath:pathname];

    xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:url options:NSXMLDocumentTidyXML error:&error];
    if(xmlDoc)
    {
        root = [xmlDoc rootElement];
    }
    else
    {
        root = [NSXMLNode elementWithName:@"root"];
        xmlDoc = [[NSXMLDocument alloc] initWithRootElement:root];
    }

    // fetch value:
    children = [root nodesForXPath:@"counter" error:&error];
    item = [children count] ? [children objectAtIndex:0] : NULL;

    // modify value:
    counter = item ? [[item stringValue] intValue] : 0;
    counter++;
    if(NULL == item)
    {
        item = [NSXMLNode elementWithName:@"counter" stringValue:@"0"];
        [root insertChild:item atIndex:0];
    }
    [item setStringValue:[[NSNumber numberWithInt:counter] stringValue]];

    // write:
    data = [xmlDoc XMLData];
    [data writeToURL:url atomically:YES];
}
2 голосов
/ 15 марта 2015

Вот мое решение проблемы - только часть, в которую я записываю файл, который был ранее прочитан и проанализирован ...

Используя решение PacMan--, я столкнулся с проблемой, что выходной файл xml не был отформатирован красиво ( без разрывов строк ).

Другой момент, я обычно предпочитаю использовать XPath для навигации по документу XML.

Мой код является частью класса, поэтому у меня есть свойство для каждого узла (NSString * cfaLayout и NSInteger bitsPerPixel):

-(BOOL) savePropertiesFile{
BOOL isSuccess=FALSE;
NSError* error;
NSXMLElement* currentElement;
NSArray* nodes;

/* parse existing url file before saving it to new url */
if([_documentUrl checkResourceIsReachableAndReturnError:&error]==YES){
    self.document=[[NSXMLDocument alloc]
                                 initWithContentsOfURL:_documentUrl
                                 options:0
                                 error:&error];

    /* check top node */
    nodes=[_document nodesForXPath:@"/ImageFormat-Properties"
                                                     error:&error];
    if([nodes count]==0){
        return FALSE;
    }

    /* cfa layout */
    nodes=[_document nodesForXPath:@"/ImageFormat-Properties/ImageFormatDetails/CFALayout[text()]"
                                                     error:&error];
    if([nodes count]>0){
        currentElement=[nodes objectAtIndex:0];
        [currentElement setStringValue:[_cfaLayout lowercaseString]];
    }
    else{
        return FALSE;
    }

    /* bitsPerPixel */
    nodes=[_document nodesForXPath:@"/ImageFormat-Properties/ImageFormatDetails/BitsPerPixel[text()]"
                                                     error:&error];
    if([nodes count]>0){
        currentElement=[nodes objectAtIndex:0];
        [currentElement setStringValue:[NSString stringWithFormat: @"%ld", (long)_bitsPerPixel]];
    }
    else{
        return FALSE;
    }
}
[_document setDocumentContentKind:NSXMLDocumentXMLKind];
[_document setCharacterEncoding:@"UTF-8"];
[_document validateAndReturnError:&error];
if(error){
    return FALSE;
}

[self setDocumentUrl:_documentSaveAsUrl];
NSData* xmlData=[_document XMLDataWithOptions:NSXMLNodePrettyPrint];
isSuccess=[xmlData writeToURL:_documentSaveAsUrl atomically:YES];

return isSuccess;

}

Может быть, кому-то пригодится ...

0 голосов
/ 16 мая 2011

Если вы не знакомы с xpath s, то я предлагаю вам прочитать их, xpath s - это способ найти узлы в дереве XML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...