Пересечение дерева 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:
метод вместо этого.