Использование NSXMLElement для добавления тега в середине блока текста - PullRequest
2 голосов
/ 05 сентября 2010

Мне нужно создать XML-документ в формате следующего типа.

Это текст о , о котором вам нужно знать.

У меня нет проблем с генерацией общего XML, но этот аспект вызывает у меня некоторые проблемы.

Спасибо, ребята

Скотт

Ответы [ 4 ]

3 голосов
/ 05 сентября 2010

Один из подходов заключается в создании изменяемой копии stringValue узла para, а затем вставке тегов вокруг текста «someMethod». Создайте новый NSXMLNode из этого, используя -[NSXMLNode initWithXMLString:error:] и замените старый NSXMLNode новым NSXMLNode. Это, вероятно, короче, но требует некоторых манипуляций со строками.

Если вы знаете, что узел para представляет собой один фрагмент текста, то вы можете использовать эту категорию в только что написанном NSXMLNode, который мне кажется более многословным, чем то, что я описал. Зависит от того, что вам нужно и насколько вам нравится возиться с NSMutableStrings. :)

@implementation NSXMLElement (ElementSplitting)

- (void)splitTextAtRangeInStringValue:(NSRange)newNodeRange withElement:(NSString *)element {
/*  This is pretty simplistic; it assumes that you're attempting to split an element node (the receiver) with a single stringValue. If you need to do anything more complicated, you'll have to do some more work. For this limited example, we need three new nodes(!):
        1. One new text node for the first part of the original string
        2. One new element node with a stringValue of the annotated part of the string
        3. One new text node for the tail part of the original string
    An alternate approach is to use -[NSXMLNode initWithXMLString:error:] after making a mutable copy of the string and modifying that string with the new markup you want.
 */
    NSXMLNode *prefaceTextNode = [[NSXMLNode alloc] initWithKind:NSXMLTextKind];
    NSXMLElement *elementNode = [[NSXMLNode alloc] initWithKind:NSXMLElementKind];
    NSXMLNode *suffixTextNode = [[NSXMLNode alloc] initWithKind:NSXMLTextKind];

    NSString *fullStringValue = [self stringValue];
    NSString *prefaceString = [fullStringValue substringToIndex:newNodeRange.location];
    NSString *newElementString = [fullStringValue substringWithRange:newNodeRange];
    NSString *suffixString = [fullStringValue substringFromIndex:newNodeRange.location + newNodeRange.length];

    [prefaceTextNode setStringValue:prefaceString];
    [elementNode setName:element];
    [elementNode setStringValue:newElementString];
    [suffixTextNode setStringValue:suffixString];

    NSArray *newChildren = [[NSArray alloc] initWithObjects:prefaceTextNode, elementNode, suffixTextNode, nil];
    for (id item in newChildren) { [item release]; }    // The array owns these now.
    [self setChildren:newChildren];
    [newChildren release];
}

@end

... и вот небольшой пример:

NSString *xml_string = @"<para>This is some text about something.</para>";
NSError *xml_error = nil;
NSXMLDocument *doc = [[NSXMLDocument alloc] initWithXMLString:xml_string options:NSXMLNodeOptionsNone error:&xml_error];

NSXMLElement *node = [[doc children] objectAtIndex:0];
NSString *childString = [node stringValue];    
NSRange splitRange = [childString rangeOfString:@"text about"];

[node splitTextAtRangeInStringValue:splitRange withElement:@"codeVoice"];
1 голос
/ 05 сентября 2010

Ух, спасибо Крису и Пикселю.

Да, изначально была ошибка, что я просто использовал квадратные скобки вокруг имени, а не тег codeVoice вокруг someMethod.

Но все хорошосейчас.Я генерирую то, что мне нужно, спасибо вам, ребята.

1 голос
/ 05 сентября 2010

Если <someMethod> на самом деле является элементом, то вам нужно создать NSXMLNode вида NSXMLTextKind (через initWithKind :), создать свой <someMethod> узел и создать еще один текстовый узел, а затем добавить все три по порядку в качестве дочерних элементов для ваш <Para> узел. Ключ заключается в создании двух текстовых частей в виде отдельных узлов.

После перечитывания вопроса, я думаю, что <someMethod> не должен был быть узлом, но должен был быть текстом? Если это так, то это просто уходящая проблема (&lt; | &gt;), но я предполагаю, что это не так просто, учитывая, кто вы есть. :)

0 голосов
/ 05 сентября 2010

Не уверен, почему мое исправление не было опубликовано ...

Это некоторый текст о someMethod , о котором вам нужно знать.

Вот чтоМне нужно повторить.

...