Пересечение дерева XML

NSXML дает Вам несколько способов исследовать древовидную структуру, представляющую XML-документ и найти узлы, представляющие интерес. Каждый подход основывается на различной концептуальной модели:

Пересечение дерева в порядке документа является, возможно, самым простым подходом. Если Вы хотите пройти через весь документ — и многократно вызвать, Вы запускаете в некотором узле в дереве — в частности корневой элемент nextNode получить следующий узел в порядке документа, пока Вы не достигаете конца документа. По пути можно запросить узлы для атрибутов интереса, таких как имя, значение, вид или уровень. Перечисление 1 иллюстрирует использование nextNode, в этом извлечении случая комментарии, использующиеся в качестве примечаний перевода для строкового значения последующего узла.

Перечисление 1  Обходя дерево XML с сообщениями nextNode

NSXMLNode *aNode = [xmlDoc rootElement];
NSMutableString *translator_notes=nil;
while (aNode = [aNode nextNode]) {
    if ( [aNode kind] == NSXMLCommentKind ) {
        if (!translator_notes) {
            translator_notes = [[NSMutableString alloc] init];
        }
        [translator_notes appendString:[aNode stringValue]];
        [translator_notes appendString:@" ========> "];
        aNode = [aNode nextNode]; // element to be translated
        [translator_notes appendString:[aNode stringValue]];
        [translator_notes appendString:@"\n"];
    }
}
if (translator_notes) {
    [translator_notes writeToFile:[NSString stringWithFormat:@"%@/translator_notes.txt", NSHomeDirectory()] atomically:YES];
    [translator_notes release];
}

Конечно, можно также пойти назад в порядке документа путем повторной отправки previousNode к каждому возвращенному объекту узла.

В то время как nextNode и previousNode возьмите Вас последовательно через представленный XML-документ, много других методов NSXMLNode помогают Вам перейти иерархически в древовидной структуре XML между родителем и дочерними узлами и среди одноуровневых узлов общего родителя. Эти методы включают children , childCount , childAtIndex: , nextSibling , и previousSibling . Следующие примеры фрагмента кода показывают, как эти методы могли бы использоваться в комбинации, чтобы пересечь одноуровневые узлы и выполнить некоторую задачу. В Перечислении 2, children и childCount методы используются, вместе с NSArray objectAtIndex: метод.

Перечисление 2  Используя дочерние элементы и childCount методы для пересечения одноуровневых узлов

NSArray *children = [[xmlDoc rootElement] children];
int i, count = [children count];
for (i=0; i < count; i++) {
    NSXMLNode *child = [children objectAtIndex:i];
    [self doSomethingWithNode:child];
}

Если Вы можете, использовать NSXMLNode childCount метод для получения числа дочерних узлов вместо отправки count к результату children. Прежний метод предлагает лучшую производительность. Пример кода в Перечислении 3 немного более прост и обходит children метод в целом.

Перечисление 3  Используя childAtIndex: и методы childCount для пересечения одноуровневых узлов

int i, count = [[xmlDoc rootElement] childCount];
for (i=0; i < count; i++) {
    NSXMLNode *child = [[xmlDoc rootElement] childAtIndex:i];
    [self doSomethingWithNode:child];
}

Еще более простой подход к той же задаче проиллюстрирован в Перечислении 4, использующем NSXMLNode childAtIndex: и nextSibling методы.

Перечисление 4  Используя childAtIndex: и методы nextSibling для пересечения одноуровневых узлов

NSXMLNode *child = [[xmlDoc rootElement] childAtIndex:0];
do {
    [self doSomethingWithNode:child];
} while ( child = [child nextSibling] );

Для движения вверх в древовидной иерархии, от дочернего узла для порождения Вы имеете parent метод. Это - единственный метод, необходимый для этого направления потому что, за исключением корневого элемента и автономных узлов, существует почти всегда непосредственное отношение от дочернего элемента к его родителю в дереве XML. (Пространство имен и узлы атрибута являются также исключением к этому правилу отношения, потому что они имеют элемент как родителя, но не являются дочерними элементами того элемента.)

Если Вы хотите более направленный поиск, можно использовать elementsForName: метод. Если Вы знаете имя дочернего элемента, отправить elementsForName: к родительскому элементу. Этот метод возвращает узлы ребенка Нсксмлелемана с соответствием имен в массиве (объект NSArray используется в случае, если больше чем у одного дочернего элемента есть указанное имя). Если необходимо иметь дело с квалифицированными к пространству имен элементами, используйте elementsForLocalName:URI: метод вместо этого.