XML数据解析

来源:互联网 发布:数据变换方法的选择 编辑:程序博客网 时间:2024/06/07 13:54

 XML:可扩展标记语言,是一种数据交换格式,解析方式分为两种,即Dom和Sax解析。

   Dom 解析,把整个数据看作是一个Dom对象,将它们一次性读入内存,功耗大,解析难度低,用到的开源库有:GDataXMlNode,XMLDictionary等。   

   Sax 解析,Sax采用逐步解析的方式,占用内存小,特点是方便,灵活,解析相对麻烦。用到的开源库为:NSXMLParser等。

NSXMLParser实现的原理是把整个xml文档一次性读出,放在一个树型结构里。在需要的时候,查找特定节点,然后对节点进行读或写

两点认识:

1、 类似如下XML文档结构,其分析是从imgList开始读取,而不是img表节点。不然就只读取一次,是不会循环的。


<imgList>

<img><src>图片地址1</src>

<name>图片名称1</name>

<url>图片指定超链接1</url>

</img>


<img><src>图片地址2</src>

<name>图片名称2</name>

<url>图片指定超链接2</url>

</img>

</imgList> 

2 在根据xml文档结构组织相关实体类定义时的基本思路:把每个新节点容器都定义描述成一个新的实体类。

下面是一个具体例子的主要代码:

   1)、获取本地xml文件中的数据需要以下几个步骤:

      1、从本地资源文件中读取文件的路径,

      2、将xml文件转化成data文件,

      3、初始化待解析的xml文件,

      4、初始化需要从xml文件中解析的元素,

      5、设置解析代理

      6、开始解析

- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

    

    //初始化用来临时存储从xml中读取到的数据

    self.workingPropertyString = [[NSMutableStringalloc]init];

    //初始化用来存储解析后的xml文件

    self.workingArray = [NSMutableArrayarray];

    

    //1.从资源文件中获取images.xml文件的路径

    NSString *strPathXml = [[NSBundlemainBundle]pathForResource:@"images"ofType:@"xml"];

    //2.xml文件转化成data文件

    self.xmlData = [[NSDataalloc]initWithContentsOfFile:strPathXml];

    //3.初始化待解析的xml

   self.parserXML = [[NSXMLParseralloc]initWithData:self.xmlData];

    

    //4.初始化需要从xml中解析的元素

    self.elementsToParse = [[NSArrayalloc]initWithObjects:@"id",@"name",@"image",@"artist",nil];

//    self.elementsToParse = [[NSArray alloc] initWithObjects:kIDStr, kNameStr, kImageStr, kArtistStr, nil];

    //5.设置解析代理

    [_parserXMLsetDelegate:self];

    //6.开始解析数据

    [_parserXMLparse];  //调用解析的代理

 }

  2)、必须实现NSXMLParserDelegate的三个代理方法

 

//1.遍例xml的节点,发现元素开始符的处理函数(即报告元素的开始以及元素的属性)

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

 

}

//2.节点有值则调用此方法,处理标签包含内容字符(报告元素的所有或部分内容)

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

{

 

}

//3.当遇到结束标记时,进入此句,保存元素各项数据,这里才是真正完成整个解析,并保存数据的最终结果的地方

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

{

 

}

还有两个代理方法可按照自己的想法选择是否实现,

//报告解析的结束

-(void)parserDidEndDocument:(NSXMLParser *)parser

{

   

}

//报告不可恢复的解析的错误

-(void)parser:(NSXMLParser *)parserparseErrorOccurred:(NSError *)parseError

{

   

}

必须实现的三个代理方法的简单实现为

1//遍例xml的节点,发现元素开始符的处理函数(即报告元素的开始以及元素的属性)

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

{

    // entry: { id (link), im:name (app name), im:image (variable height) }

    //判断elementNameimages是否相等

   if ([elementNameisEqualToString:@"images"])

{

        //相等的话,重新初始化workingEntry

self.workingEntry = [[AppRecordalloc]init];

    }

//查询指定对象是否存在,我们需要保存的那四个对象,开头定义的四个static

    //    containsObject确定数组中是否包含对象obj

    storingCharacterData = [_elementsToParsecontainsObject:elementName];

//    NSLog(@"%@",elementName);

}

2、//节点有值则调用此方法,处理标签包含内容字符(报告元素的所有或部分内容)

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

{

    if (storingCharacterData)

    {

//string添加到workingPropertyString

        [_workingPropertyStringappendString:string];


    }

}

3、//当遇到结束标记时,进入此句,保存元素各项数据,这里才是真正完成整个解析,并保存数据的最终结果的地方

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementNamenamespaceURI:(NSString *)namespaceURIqualifiedName:(NSString *)qName

{

    //判断workingEntry是否为空

    if (self.workingEntry)

    {

        if (storingCharacterData)

        {

            NSLog(@"_workingPropertyString:%@",_workingPropertyString);

            //NSString的方法,去掉字符串前后的空格

            NSString *trimmedString = [_workingPropertyStringstringByTrimmingCharactersInSet:

                                       [NSCharacterSetwhitespaceAndNewlineCharacterSet]];

            //将字符串置空

            [_workingPropertyStringsetString:@""];

            //根据元素名,进行相应的存储

            if ([elementName isEqualToString:kIDStr])

            {

                self.workingEntry.appURLString = trimmedString;

            }

            else if ([elementName isEqualToString:kNameStr])

            {

                self.workingEntry.appName = trimmedString;

            }

            else if ([elementName isEqualToString:kImageStr])

            {

                self.workingEntry.imageURLString = trimmedString;

            }

            else if ([elementName isEqualToString:kArtistStr])

            {

                self.workingEntry.artist = trimmedString;

            }

           

        }

    }

    //遇到images时,将本次解析的数据存入数组workingArray中,AppRecord对象置空

//    static int i = 0;

    if ([elementNameisEqualToString:@"images"])

    {

      

        [self.workingArrayaddObject:self.workingEntry];

        self.workingEntry =nil;

        //用于检测数组中是否已保存,实际使用时可去掉,保存的是AppRecord的地址

//      NSLog(@"_workingArray%@",_workingArray);

//       NSLog(@"entity:%@",[_workingArray[i] appURLString]);

//        i++;

    }

}




0 0
原创粉丝点击