在 NSXMLParser 中解析 xml

Posted

技术标签:

【中文标题】在 NSXMLParser 中解析 xml【英文标题】:Parsing xml in NSXMLParser 【发布时间】:2012-02-07 11:54:05 【问题描述】:

我已经阅读了许多关于如何从 xml 文件中获取文本的示例,但只是不知道如何去做。这是一个示例 xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<questions>
    <set>
        <question>Question</question>
        <answer>Answer</answer>
    </set>
</questions>

使用-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI,获取值QuestionAnswer 的最简单方法是什么?我已经连接了我的解析器委托等等。

【问题讨论】:

【参考方案1】:

要实现 NSXMLParser,你需要实现它的委托方法。

首先以这种方式启动NSXMLParser。

- (void)viewDidLoad 

    [super viewDidLoad];

    rssOutputData = [[NSMutableArray alloc]init];

    //declare the object of allocated variable
    NSData *xmlData=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:@""]];// URL that given to parse.

    //allocate memory for parser as well as 
    xmlParserObject =[[NSXMLParser alloc]initWithData:xmlData];
    [xmlParserObject setDelegate:self];

    //asking the xmlparser object to beggin with its parsing
    [xmlParserObject parse];

    //releasing the object of NSData as a part of memory management
    [xmlData release];


//-------------------------------------------------------------


-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
   attributes: (NSDictionary *)attributeDict

    if( [elementName isEqualToString:@"question"])
    

         strquestion = [[NSMutableString alloc] init];

    



//-------------------------------------------------------------


-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

       // init the ad hoc string with the value     
     currentElementValue = [[NSMutableString alloc] initWithString:string];
   else 
     // append value to the ad hoc string    
    [currentElementValue appendString:string];
  
  NSLog(@"Processing value for : %@", string);



//-------------------------------------------------------------


-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName

    if( [elementName isEqualToString:@"question"])
    
        [strquestion setString:elementName];
    

 [currentElementValue release];
  currentElementValue = nil;

上述委托方法由解析器对象在遇到特定元素的结尾时发送给它的委托。在didEndElement这个方法中,你会得到question的值。

【讨论】:

foundCharacters 中遗漏了一个 if 条件:) if (currentElementValue == nil) 最近有人用过这个代码吗?我收到“使用未声明的标识符 xmlParserObject”错误。是否缺少 IMPORT? @user3741598 只做 NSXMLParser* xmlParserObject。我认为在上面的示例代码中,解析器首先在标题中声明,因此不需要说明它的类型。至少这是我的猜测。 @Nirav 你能看看我的问题***.com/questions/43539307/…【参考方案2】:
// This one called out when it hit a starting tag on xml in your case <question>

  BOOL got = FALSE;

  - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI 

 

      if([elementName isEqualToString:@"question"])
       
         got = TRUE;
       


// This is third one to called out which gives the end tag of xml in your case </question>


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName



// This delegate is the second one to called out which gives the value of current read tag in xml

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
 

   if(got)
  
    NSLog(@"your desired tag value %@",string);
    got = FALSE; 
  

【讨论】:

【参考方案3】:

你需要实现方法

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

一旦你看到你想要抓取的(内部)文本的元素,在你的程序中设置一个标志,并用foundCharacters在标签之间找到的东西保留一个字符串。一旦你点击了didEndElement 方法,你就可以对字符串做你想做的事情并重置标志。

例如

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
  if (sawQuestion) 
    // need to check here that self->myString has been initialized
    [self->myString appendString:string];
 

didEndElement 中,您可以重置标志sawQuestion

【讨论】:

【参考方案4】:

你必须为NSXMLParserDelegate实现回调

关键是:

// called when it found an element - in your example, question or answer
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI 

// called when it hits the closing of the element (question or answer)
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI

// called when it found the characters in the data of the element
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

因此,当您点击元素时,您可以根据您点击时设置的状态设置解析器当前是否在问题或答案元素中(使用 iVar),然后当您使用 foundCharacters 回调时元素,您知道将数据分配给哪个变量(问题或答案)。

【讨论】:

以上是关于在 NSXMLParser 中解析 xml的主要内容,如果未能解决你的问题,请参考以下文章

iOS - OC - XML 解析 - NSXMLParser

NSXMLParser 将 RSS 解析为自定义对象

如何使用 NSXMLParser 解析同名的父子元素

使用 NSXMLParser 根据属性解析 XML

Iphone NSXMLParser NSCFString 内存泄漏

NSXMLParser读取XML文件并将数据显示到TableView上