Разбор атрибутов NSXMLNode в Cocoa
Учитывая следующий XML файл:
<?xml version="1.0" encoding="UTF-8"?>
<application name="foo">
<movie name="tc" english="tce.swf" chinese="tcc.swf" a="1" b="10" c="20" />
<movie name="tl" english="tle.swf" chinese="tlc.swf" d="30" e="40" f="50" />
</application>
Как я могу получить доступ к атрибутам ( "английский", "китайский", "имя", "а", "b" и т.д.) и связанным с ними значениям узлов MOVIE? В настоящее время у меня есть Cocoa возможность перемещения этих узлов, но я не понимаю, как я могу получить доступ к данным в MOVIE NSXMLNodes.
Есть ли способ сбросить все значения из каждого NSXMLNode в Hashtable и получить значения таким образом?
Используем NSXMLDocument и NSXMLNodes.
Ответы
Ответ 1
ДА! Я как-то ответил на свой вопрос.
При повторении через XML-документ вместо назначения каждого дочернего node в качестве NSXMLNode назначьте его как NSXMLElement. Затем вы можете использовать функцию attributeForName, которая возвращает NSXMLNode, к которой вы можете использовать stringValue для получения значения атрибута.
Поскольку я плохо разбираюсь в этом, вот мой прокомментированный код. Это может иметь смысл.
//make sure that the XML doc is valid
if (xmlDoc != nil) {
//get all of the children from the root node into an array
NSArray *children = [[xmlDoc rootElement] children];
int i, count = [children count];
//loop through each child
for (i=0; i < count; i++) {
NSXMLElement *child = [children objectAtIndex:i];
//check to see if the child node is of 'movie' type
if ([child.name isEqual:@"movie"]) {
{
NSXMLNode *movieName = [child attributeForName:@"name"];
NSString *movieValue = [movieName stringValue];
//verify that the value of 'name' attribute of the node equals the value we're looking for, which is 'tc'
if ([movieValue isEqual:@"tc"]) {
//do stuff here if name value for the movie tag is tc.
}
}
}
}
Ответ 2
Есть два варианта. Если вы продолжаете использовать NSXMLDocment
и у вас есть NSXMLNode *
для элемента фильма, вы можете сделать это:
if ([movieNode kind] == NSXMLElementKind)
{
NSXMLElement *movieElement = (NSXMLElement *) movieNode;
NSArray *attributes = [movieElement attributes];
for (NSXMLNode *attribute in attributes)
{
NSLog (@"%@ = %@", [attribute name], [attribute stringValue]);
}
}
В противном случае вы можете переключиться на использование NSXMLParser
. Это управляемый событиями парсер, который информирует делегата, когда он разбирает элементы (между прочим). Метод, который вы используете, parser:didStartElement:namespaceURI:qualifiedName:attributes:
- (void) loadXMLFile
{
NSXMLParser *parser = [NSXMLParser parserWithContentsOfURL:@"file:///Users/jkem/test.xml"];
[parser setDelegate:self];
[parser parse];
}
// ... later ...
- (void) parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"movie"])
{
NSLog (@"%@", [attributeDict objectForKey:@"a"]);
NSLog (@"%d", [[attributeDict objectForKey:@"b"] intValue]);
}
}