Использование NSXMLElement для добавления тега в середине блока текста
Мне нужно создать XML-документ в следующем формате.
Это некоторый текст о
Para>
У меня нет проблем с общей генерацией XML, но этот аспект вызывает у меня некоторые проблемы.
Спасибо ребята
Скотт
4 ответа
Одним из подходов является создание изменяемой копии 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"];
Вау, спасибо Крис и Пиксель.
Да, изначально было ошибкой то, что я использовал квадратные скобки вокруг имени, а не тег codeVoice вокруг someMethod.
Но сейчас все хорошо. Я генерирую то, что мне нужно, спасибо вам, ребята.
Если <someMethod>
на самом деле элемент, то вам нужно создать NSXMLNode вида NSXMLTextKind (через initWithKind:), создайте свой <someMethod>
узел, и создайте другой текстовый узел, затем добавьте все три по порядку в качестве дочерних к вашему <Para>
узел. Ключ заключается в создании двух текстовых частей в виде отдельных узлов.
Перечитав вопрос, я думаю, может быть <someMethod>
не должен был быть узлом, но должен был быть текстом? Если так, то это просто проблема (< | >)
но я предполагаю, что это не так просто, учитывая, кто ты.:)
Не уверен, почему мое исправление не было опубликовано...
Это некоторый текст о
Это то, что мне нужно повторить.